Suppose one has a set of objects which are going to do some processing which takes a while ... or might take a while. By design, the intention is that they can be used in a number of different contexts including real time with a UI and batch, perhaps automated runs. In some of those contexts it would be desirable to provide feedback to the user that something is happening, but in other contexts, there is no one there to pay attention. Does anyone have any good suggestions on how to provide this heartbeat without creating a structure that gets in the way of unattended uses?
We register implementations of the IProgressChangedHandler interface in our session service container.
If there is one registered your working class can talk against the Interface.
When not they don't.
The IProgressChangedHandler can modify a progress display on a UI, write to a log file for batch sessions,'send sonic messages or sing a song.
The Eclipse equivalent will be IProgressMonitor, very important for user interaction to keep the UI responsive when calling methods that might involve long processing... if the method don't get a valid monitor then just create an instance of NullProgressMonitor (won't do nothing when notified about progress), and as always it's considered a good practice to give the user the option to cancel the operation therefore one should check if the monitor state is canceled and stop processing.
Sounds like a perfect scenario for using a messaging service like activemq
or sonic. Fire off a message, if nothing is listening, nothing happens. We
have a presentation on open source messaging at the PUG Americas challenge
in may.
On Mar 7, 2012 12:15 AM, "Thomas Mercer-Hursh" <
I want something that is not platform specific. Messaging has the right flavor, but seems like a lot of setup for a tool one is going to run once in a while. I just want to have a structure where a developer can run the tool on demand from a UI or can set it up for a batch run nightly or whatever.
So then right thing is to define your IHeartbeat interface and have a way that works for your framework to let the worker class find out if there is an implementation or not.
For us that's our service container, where services are registered against the interfaces they implement (similar to what's holding the .NET Visual Designer together).
... Messaging has the right flavor, but seems like a lot of setup for a tool one is going to run once in a while.
in my world, a lot of setup == 30 seconds
seriously , you consider 30 seconds a "lot of setup" ?
setup:
#1 download activemq
#2 unzip activemq
#3 enable stomp in config file
#4 start activemq (command line or windows service. Choice is yours)
=== end of setup ===
runtime :
#1 update StompProperties.txt with
localhost 61613 ; or whatever server / port activemq is running on
#2 run this code
dotr.Stomp.Helper.SendMessage:ToTopic("com.integrity.myapp.info.heartbeat","some message").
seriously , you consider 30 seconds a "lot of setup" ?
It may be fast. But for in process messaging or no heartbeat required at all it's still overkill, right?
The way to go is to make it an optional component in the software architecture. And then your stomp adapter may be a great alternative implementation.
It's also fast for in-process messaging (ok, not nearly as fast as event:subscribe) but it has the added advantages of
a) cross platform. Works on linux / unix / windows
b) it's a great way of adding remote debugging
c) it can subscribe from any client, local or remote, abl or .net or javascript or php or ruby etc (we have a javascript client driving the plasma displays that listen for call events, and an abl client doing the same thing - but we don't have to write two handlers (one for events, one for messaging) )
we actually use it internally for sending messages about crud operations on any table that has been "MessageEnabled" (tm) , which can be millions of record updates per day.
try it. you may like it
try it. you may like it
As one option among others
I'm surprised that no one has mentioned class events...
For my unterstanding the variable logging facility should be a session service used by the worker class. And not the other way round.
For an event someone would have the to SUBSCRIBE the session service to an event of the worker class right after invoking the constructor (and what if the worker class does start with trace worthy action in the constructor?).
I don't believe that's practical in this context, do you?
I think we have had some cross talk. The question here is not about logging. Rather it is about the issue when one has a UI with a person in front of it and a long running task that it is useful to give him or her some idea that the process is actually proceding. If the task is running in batch, then this is not required. So, if the task publishes an event and the UI subscribes, then the UI can report, but the routine that runs the task in batch either doesn't subscribe or does something else with the "news".
tamhas wrote:
I think we have had some cross talk. The question here is not about logging. Rather it is about the issue when one has a UI with a person in front of it and a long running task that it is useful to give him or her some idea that the process is actually proceding. If the task is running in batch, then this is not required.
right, just do yourself a favour and take a look at IProgressMonitor... http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcore%2Fruntime%2FIProgressMonitor.html
tamhas wrote:
So, if the task publishes an event and the UI subscribes, then the UI can report, but the routine that runs the task in batch either doesn't subscribe or does something else with the "news".
why loose coupling using events (who'll decide on the event name and how should one know that info) when you can have a interface contract?
What relevance does an Eclipse interface have to a standalone ABL tool?
tamhas wrote:
What relevance does an Eclipse interface have to a standalone ABL tool?
very funny, if you can spare a bit of your precious time and read just the description of that interface you'll probably see it's a good fit for your requirements... but feel free to reinvent your ABL'ish wheel
Seems like a sledge hammer when a tack hammer is called for ...
tamhas wrote:
Seems like a sledge hammer when a tack hammer is called for ...
Sounds like good OO design to me ...
If you do use the interface approach, you can make any type the consumer of progress monitoring state information. Furthermore, the implementation of the IProgressMonitor could provide output via a UI widget, a log file or whatever.
UI.CaptureScreen(input poMonitor as IProgressMonitor)
Util.Logger(input poMonitor as IProgressMonitor)
Util.BatchJob(input poMonitor as IProgressMonitor)
You could decorate the classes instead of passing as constructor arguments, which would give you way more flexibility in terms of which types (or even instances) you monitor.
-- peter
My comment wasn't about whether to use an interface, but about a very rich interface for a very simple problem.
Still, there is something appealing about events since they are even more uncoupled.