Sometimes, we're so smart, we miss the obvious.
I'm redesigning my SSHWrapper/TestSSH (yes, it's in that stage of its career where it changes its artistic name every now and then), my C++ wrapper around libssh2 using boost asio.
I've finished work on SSHSession, which provides SSH session (uncanny, heh?) functionality. Another class will provide SSH Channel/command execution functionality.
I was working on a text to post here, detailing how SSHSession worked, when I had an idea for an addition to SSHSession. You see, it connects in the constructor and disconnects in the destructor, but something could go wrong during disconnect.
So, I added to its public interface a method that forcibly terminates a connection, controlled by a flag, so that it could only be invoked if the normal disconnection process failed. This forced terminate would be based on the premise that the disconnect had failed on the SSH level and would attempt a TCP (i.e., socket) disconnect, leaving the server to clean up any SSH mess on its side.
So, it would flow like this:
- SSHSession goes out of scope on the client code, thus invoking the destructor.
- Destructor performs SSH cleanup.
- SSH cleanup fails. We set a flag that will allow the client to invoke SSHSession's forced disconnection.
I coded it enthusiastically, thinking how cool it was that I was making my class more robust, and user-friendly. And I was updating the text at the same time. And then, just before posting it here, I decided to run a test on this brilliant new idea of mine. Not that it needed, of course, being such a brilliant idea.
Once again, I wrote the test code and updated the text. And then, the obvious hit me!
Despite my best intentions, the destructor finishes successfully and the object is, well... destroyed. The client code isn't even aware that something failed. And even it it was, there is no object upon which to invoke my Wonder-Terminate-Forced anymore. Because, you know, that's one of the expected consequences of a destructor finishing its execution successfully.
And the point is... writing the post helped me visualize what I was doing, and helped me getting to the error of my design sooner. I'll have to do this more often - write a post after a coding session, even if I end up not publishing it. It forces me to think about what I've done, and to review it.
And that's always a good thing.