Spring MessageTemplate Issue - multithreading

I'm facing a problem after the migration from Spring 2.5, Flex 3.5, BlazeDS 3 and Java 6 to Spring 3.1, Flex 4.5, BlazeDS 4 and Java 7. I've declared a ClientFeed in order to send a sort of "alarm" messages to the flex client. There are three methods those alarms are sent. The first one is via snmp traps, a thread is started and wait for any trap, as one is received an alarm will be sent. The second method is via a polling mechanism, at the beginning of the web application a thread is started and will poll after a constant amount of time the alarms and send them to the client. The third method is the explicit poll command from the user, this will call a specific function on the dedicated service. This function uses then the same algorithm used in the second methods to perform a poll and shall send those alarms to the client.
The problem is that after the migration the first two methods are working without a problem, but the third one doesn't. I suspect there is a relation with the threads. Is there any known issue between messagetemplate and the threads with the new frameworks ?
Here is a snapshot of the used client feed:
#Component
public class ClientFeed {
private MessageTemplate messageTemplate;
#Autowired
public void setTemplate(MessageTemplate messageTemplate) {
this.messageTemplate = messageTemplate;
}
public void sendAlarmUpdate(final Alarm myAlarm) {
if (messageTemplate != null) {
System.out.println("Debug Thread: " + Thread.currentThread().getName());
messageTemplate.send(new AsyncMessageCreator() {
public AsyncMessage createMessage() {
AsyncMessage msg = messageTemplate.createMessageForDestination("flexClientFeed");
msg.setHeader("DSSubtopic", "Alarm");
msg.setBody(myAlarm);
return msg;
}
});
}
}
}
By the three methods I reach this piece of code and the displayed thread name are respectively: "Thread-14", "Thread-24" and "http-bio-80-exec-10".

I solved the problem by creating a local thread on the server to perform the job. Therewith the client feed is called via this new created thread instead of the http-thread.

Related

Firing CDI-Events within a thread

Within an Vaadin application I am planning to implement an asynchronous result-overview for a method.
The result overview contains a table for possible results. These results should generate while a backend-method is running asynchronous in a thread. Communication between the backend and frontend of the application is planned with using CDI-Events (information for the result will be in the CDI-Event).
I already achieved to fire CDI-Events, put them into the result-table and display the table after the method is finished. But when I execute the method within a thread (so the view is displayed and events get inserted instead of waiting to see the complete table), my CDI-Events won't fire (or get received).
Is there any way to work this out? I read about receiving CDI-Events asynchronous (blog entry), but I did not find anything about firing events within a thread...
WildFly 10.0.1.Final, Java 8, Java-EE 7 and Vaadin 7.6.6.
Thread, which should fire CDI-Events:
public class Executer implements Runnable{
#Override
public void run(){
// Here will be the backend-method invocation for firing CDI-Events
// CDI-Dummy-Event - Does not fire properly. receiveStatusEvent() does not invoke
BeanManager beanManager = CDI.current().getBeanManager();
beanManager.fireEvent(new ResultEvent("Result event example"));
}
}
Bean which receives CDI-Events
public class EventReceiver implements LoggingProvider{
public EventReceiver(){
}
public void receiveStatusEvent(#Observes ResultEvent event) {
this.info("Event received: " + event.toString());
}
}
Starting the thread with help from ManagedExecutorService
public void executeAsynchBackendMethod(){
// CDI-Dummy-Event works - receiveStatusEvent() invokes correctly
BeanManager beanManager = CDI.current().getBeanManager();
beanManager.fireEvent(new ResultEvent("Result event example"));
/* The following alternative starts a thread, but the events, which are fired in the run() method, do not take any action in the receiveStatusEvent() method */
// Getting managedExecuterService
this.managedExecuterService = (ManagedExecutorService) new InitialContext().lookup("java:comp/DefaultManagedExecutorService");
// Getting Instance of executer-Runnable (for injecting the backend-service afterwards)
Instance<Executer> executerInstance = CDI.current().select(Executer.class);
Executer executer = executerInstance.get();
// Start thread
this.managedExecuterService.submit(executer);
}
In CDI 1.2 and below, events are strictly synchronous. In CDI 2.0 there is already an implemented version of asynchronous events (in Weld) but I suppose you are stuck with 1.2.
That means (as the blog post you read suggests), you can make use of the infamous EJBs.
As for why CDI does not work in this case - I would say this is all thread-bound. In other words in that given thread where you fire the event you have no observer to be triggered.

How do I cleanly shutdown a distributed ActivePivot setup?

We have an ActivePivot cube that is a polymorphic cube (2 nodes) where 1 node is itself a horisontally distributed cube (8 nodes). Running in Tomcat using JGroup TCP for distribution. It is restarted on a daily basis, but every time it is shut down (node services are stopped in sequence), various errors show up in the logs. This is harmless, but anoying from a monitoring perspective.
Example from one day (all same node):
19:04:43.100 ERROR [Pool-LongPollin][streaming] A listener dropped (5f587379-ac67-4645-8554-2e02ed739924). The number of listeners is now 1
19:04:45.767 ERROR [Pool-LongPollin][streaming] Publishing global failure
19:05:16.313 ERROR [localhost-start][core] Failed to stop feed type MDXFEED with id A1C1D8D92CF7D867F09DCB7E65077B18.0.PT0
Example from another day (same error from multiple different nodes):
19:00:17.353 ERROR [pivot-remote-0-][distribution] A safe broadcasting task could not be performed
com.quartetfs.fwk.QuartetRuntimeException: [<node name>] Cannot run a broadcasting task with a STOPPED messenger
Does anyone know of a clean way to shut down a setup like this?
Those errors appear because on application shutdown the ActivePivotManager is aggressively stopping the distribution, without waiting for each distributed ActivePivot to be notified that other cubes have been stopped.
To smoothly stop distribution you can use the methods from the DistributionUtil class. For instance:
public class DistributionStopper {
protected final IActivePivotManager manager;
public DistributionStopper (IActivePivotManager manager){
this.manager = manager;
}
public void stop(){
// Get all the schemas from the manager
final Collection<IActivePivotSchema> schemas = manager.getSchemas().values();
// To store all the available messengers
final List<IDistributedMessenger<?>> availableMessengers = new LinkedList<>();
// Find all the messengers
for(IActivePivotSchema schema : schemas){
for(String pivotId : schema.getPivotIds()){
// Retrieve the activePivot matching this id
final IMultiVersionActivePivot pivot = schema.retrieveActivePivot(pivotId);
if(pivot instanceof IMultiVersionDistributedActivePivot){
IDistributedMessenger<IActivePivotSession> messenger = ((IMultiVersionDistributedActivePivot) pivot).getMessenger();
if(messenger != null){
availableMessengers.add(messenger);
}
}
}
}
// Smoothly stop the messengers
DistributionUtil.stopMessengers(availableMessengers);
}
}
Then register this custom class as a Spring bean depending on the activePivotManager singleton bean, in order to have its destroyMethod called before the one of the manager.
#Bean(destroyMethod="stop")
#DependsOn("activePivotManager")
public DistributionStopper distributionStopper(IActivePivotManager manager){
return new DistributionStopper(manager);
}

Accessing WinForm UI from Rhino Service Bus consumer [duplicate]

This question already has answers here:
Invoke or BeginInvoke cannot be called on a control until the window handle has been created
(8 answers)
Closed 9 years ago.
I have a WinForm screen that is also a message consumer (using Rhino ESB). If I try to update anything on the screen when I receive a message, nothing happens. A call to Invoke gives me an error that the handle is not created. The form is definitely created though, I'm firing a message on button click on the form and the background process sends a message back. It's with this return message I want to update the UI.
THIS IS NOT A DUPLICATE QUESTION, NONE OF THE SUGGESTED SOLUTIONS WORK.
I believe the difference here may be because I'm using Rhino Service bus. Rhino may be constructing a separate instance of my form rather than the one I'm using. I think what I probably need to do is to have Rhino use my instance of the form as the consumer by passing my instance into the IoC container Rhino is using. Another alternative is to move the Consumer off to it's own class and inject my Form into the consumer, and put a public method on my Form for the Consumer to use. This may work fine with my app because this is the main form and will never be disposed unless the app is closed. This would become problematic on another form that may be instantiated multiple times. Perhaps I could have my form "observe" another static object that a separate Consumer class updates. Please give suggestions as to the best approach.
public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent>
{
public void Consume(MoveJobCompletedEvent message)
{
// This does nothing!
txtLogs.Text = "\nJob completed!";
}
}
This throws an error:
this.BeginInvoke((MethodInvoker)delegate
{
txtLogs.Text += "\nJob job completed!";
});
ERROR: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
It seems that you're consuming a JobCompleted event before the window handle is created. You could try the following:
public partial class MainForm : Form, ConsumerOf<MoveJobCompletedEvent>
{
public void Consume(MoveJobCompletedEvent message)
{
if (!this.HandleCreated)
return;
this.BeginInvoke((MethodInvoker)delegate
{
txtLogs.Text += "\nJob job completed!";
});
}
}

Windows Service and multithreading

Im working on a Windows Service in which I would like to have two threads. One thread should look for updates (in a RSS feed) and insert rows into a DB when updates is found.
When updates are found I would like to send notification via another thread, that accesses the DB, gets the messages and the recipients and then sends notifications.
Perhaps the best practice isn't to use two threads. Should I have db-connections in both threads?
Could anyone provide me with tips how to solve this?
The major reason to make an application or service multithreaded is to perform database or other background operations without blocking (i.e. hanging) a presentation element like a Windows form. If your service depends on very rapid polling or expects db inserts to take a very long time, it might make sense to use two threads. But I can't imagine that either would be the case in your scenario.
If you do decide to make your service multithreaded, the two major classes in C# that you want to look into are BackgroundWorker and ThreadPool. If you want to do multiple concurrent db inserts (for example, if you want to execute an insert for each of multiple RSS feeds polled at the same time), you should use a ThreadPool. Otherwise, use a BackgroundWorker.
Typically, you'd have a db access class that would have a method to insert a row. That method would create a background worker, add DoWork handler to some static method in that db access class to the background worker, then call DoWorkAsync. You should only have db connection settings in that one class in order to make maintaining the code easier. For example:
public static class DbAccess
{
public void InsertRow(SomeObject entity)
{
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += InsertRow_DoWork;
bg.RunWorkerCompleted += InsertRow_RunWorkerCompleted;
bg.RunWorkerAsync(entity);
}
private void InsertRow_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bg = sender as BackgroundWorker;
SomeObject entity = e.Argument as SomeObject;
// insert db access here
}
private void InsertRow_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// send notifications
// alternatively, pass the InsertRow method a
// delegate to a method in the calling class that will notify
}
}

Silverlight - Waiting for asynchronous call to finish before returning from a method

I have a Silverlight application that uses WCF services and also uses the Wintellect Power Threading library to ensure logic executes fully before the application continues. This is achieved by calling back to the application using delegates so it can continue after the service call has completely finished.
I wish to achieve the same thing in another part of my application but without the use of callbacks e.g. call method that uses WCF service to say load an object from the database, wait for this to return and then return the Id of the object from the original method called.
The only way I could see to do this was to carry out the call to the WCF service in a helper library which loads the object on a different thread and the original method would keep checking the helper library (using static variables) to wait for it to complete and then return it.
Is this the best way to achieve this functionality? If so here are details of my implementation which is not working correctly.
public class MyHelper
{
private static Thread _thread;
private static User _loadedObject;
public static GetUser()
{
return _loadedObject;
}
public static void LoadObject(int userId)
{
_loadedObject = null;
ParameterizedThreadStart ts = new ParameterizedThreadStart(DoWork);
_thread = new Thread(ts);
_thread.Start(userId);
}
private static void DoWork(object parameter)
{
var ae = new AsyncEnumerator();
ae.BeginExecute(DoWorkWorker(ae, Convert.ToInt32(parameter)), ae.EndExecute);
}
private static IEnumerator<Int32> DoWorkWorker(AsyncEnumerator ae, int userId)
{
// Create a service using a helper method
var service = ServiceHelper.GetService<IUserServiceAsync>();
service.BeginGetUserById(userId, ae.End(), null);
yield return 1;
_loadedObject = service.EndGetUserById(ae.DequeueAsyncResult());
_thread.Abort();
}
}
My method then is:
public int GetUser(int userId)
{
MyHelper.LoadObject(userId);
User user = MyHelper.GetUser();
while (user == null)
{
Thread.Sleep(1000);
user = MyHelper.GetUser();
}
return user.Id;
}
The call to the get the user is executed on a different thread in the helper method but never returns. Perhaps this is due to the yield and the calling method sleeping. I have checked the call to get the user is on a different thread so I think everything should be kept separate,
The whole construct you are using does not match current best practices of Silverlight. In Silverlight your data access methods (via WebServices of course) are executed asynchronously. You should not design around that, but adapt your design accordingly.
However calling services sequentially (which is different than synchonously) can be valid in some scenarios. In this blog post I have shown how to achieve this by subscribing the Completed event of the remote call and block the UI in the meantime, with which the workflow looks and feels like normal async calls.
I believe calls to the server from Silverlight apps use events that fire on the UI thread; I think that's part of the Silverlight host environment in the browser and can't be worked around. So trying to call back to the server from another thread is never going to end well. If you are waiting in program code in the UI thread, your never going to get the call result events from your WCF calls.
You can simulate a synchronous call from a non-UI thread with a callback on the UI thread, but that is probably not what you want. It's better to bite the bullet and make your program logic work with the async calls Silverlight gives you.
If you code against the Interface created for your service reference you can call the Begin and End methods 'synchronously' for each one of your service calls, we then pass in an Action<T> to execute after the End methods has completed. Take note that you have to do this from a dispatcher. This is very close to making a synchronous call as the code to run after the call is still written where the call is made, and it executes after the service call is completed. It does however involve creating wrapper methods but we also worked around that by hiding our wrappers and generating them automatically. Seems like a lot of work but isn't, and ends up being more elegant than all the event handlers etc. Let me know if you need more info on this pattern

Resources