Circular Reference...
Telling you about a problem that we faced today. We are writing a handheld application for Windows CE. The application communicates with a Java based base station, using a web service. We call a web service on the base station that sends back a string of commands separated by tildes. These commands contain information regarding the UI and the behavior of the application. Like there is a Message command which means a label control has to be rendered on the form and there is an accept command that means a textbox has to be rendered on the form. These commands contain information regarding the placing of the control, the behavior, the contents, etc.
Now the design was something like this. There is a main controller that controls the entire flow of the application. It executes all the commands one by one. There is a command parser which takes this string of commands and parses it into different command objects. There is a GUI Controller that renders these commands into windows form controls. So the typical thing here is that the application is partially sequential and partially event driven. The commands have to be executed in the sequence that we receive them. But if we encounter an accept command (which means a textbox has to be rendered on the form!), then the application switches to event driven mode, where we have to wait for the user input.
So the main controller has a start() method that triggers the entire flow of events. This method calls a host of methods and initializes a host of objects by calling their constructors etc. until an accept (textbox) command is encountered. Once this is done, the control returns. Now when the user provides its input to the textbox and presses enter, we have written an event handler, that stores the response of the user in the accept command, and then calls the next command. After that the command execution sequence is resumed.
There is also an end and a terminate command. Now the end command means the end of batch and the terminate means the application is closed. After the end of one batch, the data taken from the user is sent to the host. Which means a web service is called. The web service on the base station sends the data to the back end main frame system and sends the next batch of commands. For this process, we have a SendMessageToBS() method. This method is called from the Execute() method of the End Command object. This method calls the Start() method of the Main controller and this starts a loop.
Problem: we enter a loop which never ends. In a way what we were doing was we were calling the SendMessageToBS() method from Start() (of course there were a host of other things that we were doing in between) and then we are calling Start() from SendMessageToBS(). So we are not returning the control to where it started from at all.
This was increasing the stack size and there were memory issues because we were writing for a handheld device.
The thing is we discovered this problem late in the development process and for once me, my team mate and my team lead were pretty tense about the situation. What are we going to do. Are we going to have to scrap the entire code and go back to formula? How much refactoring is required after all?
So we went back to the whiteboard. And started with drawing a sequence diagram of the entire sequence of events. The solution was quite easy actually. We just needed to put in some thought and it is in a way amazing that we didn’t think of this circular reference back during the design phase.
The solution: We would create a custom event (delegates and shit!). write an event handler for this event which would just call the Start() method of the Main controller, triggering the entire sequence of commands. Now we call the start() method from the main application on load. Once the entire sequence is over, and we send the data, we just raise this event and return. Our initial problem was that the control was not returning to its point of origin. This was increasing the size of the stack. This problem is solved now. The control returns to its origin freeing all the occupied resources and a new sequence of processing is started.
It was fun. Problems like these at times really keep you going. This is a problem that is really worth spending time on. And what I am really satisfied with is that we didn’t have to spend a lot of time on finding a solution of this problem. It is the simple problems that I am really worried about. I think getting a good book of puzzles by authors like Shakuntala Devi and solving those problems would really help me in thinking fast and solving easy problems.