I have to work with some legacy code written in a "push" callback style. The architecture looks like this (pseudo-Java)
public interface Callback
{
public void consumeData(Object data);
}
public class Worker // The legacy class
{
private Callback cb;
public Worker(..., Callback cb)
{
this.cb = cb;
...
}
public void execute()
{
...
for (each output object) cb.consumeData(obj);
...
}
}
public class Consumer implements Callback
{
public void doSomething()
{
Worker w = new Worker(..., this);
w.execute();
...
}
public void consumeData(Object data)
{
// process one data object
}
}
The problem with this is the deep coupling between the producer and consumer.
I want to write a thin adapter that will encapsulate the producer and run it in a separate thread, providing a simple Iterator based interface, essentially hasNext()
and next()
methods. I intend to use a SynchronousQueue: the producer will put()
objects and the adapter will take()
them on each next()
call. SynchronousQueue will handle all the synchronization for me and is a good fit for this problem. While the happy path is conceptually simple, I can see that there will be tricky issues around termination and exception handling.
For example, upon return from w.execute(), which means the producer has queued the last data object, the producer thread must ensure that it waits until the consumer has retrieved the last object from the SynchronousQueue. There will also be cleanup issues if either the producer or consumer terminates abnormally.
Rather than reinvent the wheel I thought I'd ask here if someone has already worked out the best approach. I'm not looking for code, but a pointer to a discussion of the issues... and no, this is not homework.