Sample activated application
In today’s post we're providing a sample application skeleton that may be used to play with External Activator, as well as serve as a base for writing custom activated applications.
A file with source code of the application is attached to this post and you can get it by clicking here.
The sample assumes a usage scenario where the activated application is used to offload some CPU-intensive computation from Sql Server. Whenever there’s some work to be done, Sql Server creates a conversation and sends a RequestMessage on it. The message contains some application-specific binary payload. The activated application receives such message, performs the computation and sends back a ResponseMessage containing the results of the computation. At this point Sql Server may decide to end the conversation or keep sending more RequestMessages on the same conversation. Upon receiving error or end conversation messages, the activated application will end its end of the conversation (and write an entry to Windows Event Log in case of error message). For the purpose of this sample, the “CPU-intensive computation” is just calculating an MD5 hash of the incoming payload.
Note that some users may prefer to insert the result directly into database table rather than sending a response message. However, this sample chooses a response message approach, since it provides better decoupling between the activated application and database schema.
The application is somewhat generic in the sense that it is passed the location of the queue it should read messages from as command line arguments. That way, it may be compiled once and used for servicing more than just single application queue. In order to make it work, you need to make sure the first 4 command line arguments External Activator passes to the app are:
- The Sql Server instance to connect to.
- The name of the database where the application queue is located.
- The name of the schema where the application queue is located.
- The name of the application queue.
Luckily, External Activator is able to generate these arguments based on the contents of the event notification message received (the Sql-generated message that triggers launching the user app). All you need to do is to configure the LaunchInfo section of the EAService.config file like this:
<LaunchInfo>
<ImagePath>c:\test\MessageProcessingApplication.exe</ImagePath>
<CmdLineArgs> %sqlserver% %database% %schema% %queue% </CmdLineArgs>
<WorkDir>c:\test</WorkDir>
</LaunchInfo>
One more thing: The example app requires a specific Windows Event Log source to exist and we didn’t want to force you to play with the code using admin privileges. Therefore, prior to running the main app, the event source needs to be explicitly created. For your convenience, the code includes helpers to create and destroy the event log source. In order to create it, simply execute the app with CreateLogSource command line argument (for deleting the source, use DeleteLogSource). You need to do that as administrator (elevated).
That's it for now; next time we’ll provide a step-by-step guide how to configure External Activator so that this simple app may be tested, as well as how to troubleshoot any issues.
Comments
Anonymous
March 10, 2010
Thank you very much !! I have been waiting to see a sample app from you guys on how to interact with the queue in a good way. I can definitely use your ideas in the code I have played around with. > next time we’ll provide a step-by-step guide how to configure Great - don't hold back !!Anonymous
April 20, 2010
I'm using Sql Server 2005. Does the EA Sample apply only to Sql 2008 or can I use it on Sql 2005? At one time there was EA example code but I can't find it anymore.Anonymous
June 21, 2010
Sample applications examples are worthy. I would like to come here again for further help.Anonymous
June 22, 2010
> next time we’ll provide a step-by-step guide how to configure Hope 'next time' is soon!Anonymous
July 14, 2010
where the heck is the sample app? dang it?Anonymous
July 14, 2010
@Stacy: You can use it on Sql 2005 as well. @Stacy, brotherjay: The link inside the post got broken by recent msdn blogs reorganization, but you should be able to get to the code by clicking "Program.cs" at the bottom of the post.Anonymous
November 14, 2010
The comment has been removedAnonymous
November 15, 2010
@WimVM Could you please clarify what behavior are you expecting? From what you're saying, the correct exception has been thrown, so I'm not sure what the problem is.Anonymous
November 20, 2010
Since the payload processing is done inside the reader loop, does the the db connection stay open all that time? What if processing takes time, like doing file i/o or a web request, is this the appropriate pattern to use?Anonymous
November 22, 2010
@Stacy: This pattern is useful when you need the external processing (i/o, web request) to be done transactionally with regard to receiving the message. In order to free the connection before proceeding to do the real work, you would have to commit the receive. What if the external processing fails - there's no easy way to put the message back in the queue for a retry. If you keep the transaction open, you can just do a rollback in such situation and the message is not lost. Of course feel free to change the pattern if your particular circumstances don't require these guarantees - the code was provided for the most common case, but is by no means perfect for all use cases.Anonymous
January 04, 2011
One significant omission from this sample is handling of a failure in the ProcessMessage method. If that method were to call a web service that was down or otherwise ran into trouble, there is no code to rollback the transaction (to effectively "un-receive" the message so it isn't lost.Anonymous
January 12, 2011
@Mark Freeman When the ProcessMessage fails, it will/should throw an exception, which will bubble up and eventually leave the "using(SqlTransaction)" block. That will cause the transaction to be rolled back on the server, effectively putting the received message back into the queue. Of course, the error should not crash the app as it does in the sample, but specific error handling is a business logic that cannot be included in a generic sample. The message, however, will not be lost as you're implying.Anonymous
March 02, 2011
Can you provide step by step configuration of external activation in sql server 2005Anonymous
December 24, 2011
I’m hesitant in using this since the activated application is required to be a console application. How would this behave in a non-interactive server environment where there is no logged-on user? Will there be a pop-up command window if there is an interactive user? Will they see a cmd window? what if they close it by-mistake? Furthermore, how can an infinite dequeue loop be avoid in case of failure, I mean what is the exact condition for future activation, the activated application can exit for a variety of reasons, what are your criteria for consecutive activations? It seems that a DLL hosting environment would be more appropriate for this…Anonymous
December 24, 2011
Following on my previous comment, can you please explain and share the code on how to write a custom external activator listener?Anonymous
January 17, 2012
Can you please provide a step by step sample that includes settting up the queues in database and receiving the message using External Activator?Anonymous
February 10, 2013
I get a 404 page when trying to download the sampleAnonymous
March 11, 2013
Hello, I tried a similar application (created by myself) which will create a new file when the service activate it. But I never see any new file. Can you please provide a complete sample?