How to properly canalize multithreaded message flow in a single threaded service? - wpf

In a WPF application, I have a 3rd party library that is publishing messages.
The messages are like :
public class DialectMessage
{
public string PathAndQuery { get; private set; }
public byte[] Body { get; private set; }
public DialectMessage(string pathAndQuery, byte[] body)
{
this.PathAndQuery = pathAndQuery;
this.Body = body;
}
}
And I setup the external message source from my app.cs file :
public partial class App : Application
{
static App()
{
MyComponent.MessageReceived += MessageReceived;
MyComponent.Start();
}
private static void MessageReceived(Message message)
{
//handle message
}
}
These messages can be publishing from multiple thread at a time, making possible to call the event handler multiple times at once.
I have a service object that have to parse the incoming messages. This service implements the following interface :
internal interface IDialectService
{
void Parse(Message message);
}
And I have a default static instance in my app.cs file :
private readonly static IDialectService g_DialectService = new DialectService();
In order to simplify the code of the parser, I would like to ensure only one message at a time is parsed.
I also want to avoid locking in my event handler, as I don't want to block the 3rd party object.
Because of this requirements, I cannot directly call g_DialectService.Parse from my message event handler
What is the correct way to ensure this single threaded execution?
My first though is to wrap my parsing operations in a Produce/Consumer pattern. In order to reach this goal, I've try the following :
Declare a BlockingCollection in my app.cs :
private readonly static BlockingCollection<Message> g_ParseOperations = new BlockingCollection<Message>();
Change the body of my event handler to add an operation :
private static void MessageReceived(Message message)
{
g_ParseOperations.Add(message);
}
Create a new thread that pump the collection from my app constructor :
static App()
{
MyComponent.MessageReceived += MessageReceived;
MyComponent.Start();
Task.Factory.StartNew(() =>
{
Message message;
while (g_ParseOperations.TryTake(out message))
{
g_DialectService.Parse(message);
}
});
}
However, this code does not seems to work. The service Parse method is never called.
Moreover, I'm not sure if this pattern will allow me to properly shutdown the application.
What have I to change in my code to ensure everything is working?
PS: I'm targeting .Net 4.5
[Edit] After some search, and the answer of ken2k, i can see that I was wrongly calling trytake in place of take.
My updated code is now :
private readonly static CancellationTokenSource g_ShutdownToken = new CancellationTokenSource();
private static void MessageReceived(Message message)
{
g_ParseOperations.Add(message, g_ShutdownToken.Token);
}
static App()
{
MyComponent.MessageReceived += MessageReceived;
MyComponent.Start();
Task.Factory.StartNew(() =>
{
while (!g_ShutdownToken.IsCancellationRequested)
{
var message = g_ParseOperations.Take(g_ShutdownToken.Token);
g_DialectService.Parse(message);
}
});
}
protected override void OnExit(ExitEventArgs e)
{
g_ShutdownToken.Cancel();
base.OnExit(e);
}
This code acts as expected. Messages are processed in the correct order. However, as soon I exit the application, I get a "CancelledException" on the Take method, even if I just test the IsCancellationRequested right before.

The documentation says about BlockingCollection.TryTake(out T item):
If the collection is empty, this method immediately returns false.
So basically your loop exits immediately. What you may want is to call the TryTake method with a timeout parameter instead, and exit your loop when a mustStop variable becomes true:
bool mustStop = false; // Must be set to true on somewhere else when you exit your program
...
while (!mustStop)
{
Message yourMessage;
// Waits 500ms if there's nothing in the collection. Avoid to consume 100% CPU
// for nothing in the while loop when the collection is empty.
if (yourCollection.TryTake(out yourMessage, 500))
{
// Parses yourMessage here
}
}
For your edited question: if you mean you received a OperationCanceledException, that's OK, it's exactly how methods that take a CancellationToken object as parameter must behave :) Just catch the exception and exit gracefully.

Related

Hystrix Circuit breaker not opening the circuit

I am implementing Circuit breaker using Hystrix in my Spring boot application, my code is something like below:
#service
public class MyServiceHandler {
#HystrixCommand(fallbackMethod="fallback")
public String callService() {
// if(remote service is not reachable
// throw ServiceException
}
public String fallback() {
// return default response
}
}
// In application.properties, I have below properties defined:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
hystrix.command.default.circuitBreaker.requestVolumeThreshold=3
hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds=30000
hystrix.threadpool.default.coreSize=4
hystrix.threadpool.default.metrics.rollingStats.timeInMilliseconds=200000
I see that the fallback() is getting called with each failure of callService(). However, the circuit is not opening after 3 failures. After 3 failures, I was expecting that it will directly call fallback() and skip callService(). But this is not happening. Can someone advise what I am doing wrong here?
Thanks,
B Jagan
Edited on 26th July to add more details below:
Below is the actual code. I played a bit further with this. I see that the Circuit opens as expected on repeated failured when I call the remote service directly in the RegistrationHystrix.registerSeller() method. But, when I wrap the remote service call within Spring retry template, it keeps going into fallback method, but circuit never opens.
#Service
public class RegistrationHystrix {
Logger logger = LoggerFactory.getLogger(RegistrationHystrix.class);
private RestTemplate restTemplate;
private RetryTemplate retryTemplate;
public RegistrationHystrix(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
retryTemplate = new RetryTemplate();
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(1000l);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(3);
retryTemplate.setRetryPolicy(retryPolicy);
}
#HystrixCommand(fallbackMethod = "fallbackForRegisterSeller", commandKey = "ordermanagement")
public String registerSeller(SellerDto sellerDto) throws Exception {
String response = retryTemplate.execute(new RetryCallback<String, Exception>() {
#Override
public String doWithRetry(RetryContext context) {
logger.info(String.format("Retry count %d", context.getRetryCount()));
return restTemplate.postForObject("/addSeller", sellerDto, String.class);
}
});
return response;
}
public List<SellerDto> getSellersList() {
return restTemplate.getForObject("/sellersList", List.class);
}
public String fallbackForRegisterSeller(SellerDto sellerDto, Throwable t) {
logger.error("Inside fall back, cause - {}", t.toString());
return "Inside fallback method. Some error occured while calling service for seller registration";
}
}
Below is the service class which in turn calls the above Hystrix wrapped service. This class in turn is invoked by a controller.
#Service
public class RegistrationServiceImpl implements RegistrationService {
Logger logger = LoggerFactory.getLogger(RegistrationServiceImpl.class);
private RegistrationHystrix registrationHystrix;
public RegistrationServiceImpl(RegistrationHystrix registrationHystrix) {
this.registrationHystrix = registrationHystrix;
}
#Override
public String registerSeller(SellerDto sellerDto) throws Exception {
long start = System.currentTimeMillis();
String registerSeller = registrationHystrix.registerSeller(sellerDto);
logger.info("add seller call returned in - {}", System.currentTimeMillis() - start);
return registerSeller;
}
So, I am trying to understand why the Circuit breaker is not working as expected when using it along with Spring RetryTemplate.
You should be using metrics.healthSnapshot.intervalInMilliseconds while testing. I guess you are executing all 3 request within default 500 ms and hence the circuit isn't getting open. You can either decrease this interval or you may put a sleep between the 3 requests.

APACHE FLINK AggregateFunction with tumblingWindow to count events but also send 0 if no event occurred

I need to count events within a tumbling window. But I also want to send events with 0 Value if there were no events within the window.
Something like.
windowCount: 5
windowCount: 0
windowCount: 0
windowCount: 3
windowCount: 0
...
import com.google.protobuf.Message;
import org.apache.flink.api.common.functions.AggregateFunction;
import org.skydivin4ng3l.cepmodemon.models.events.aggregate.AggregateOuterClass;
public class BasicCounter<T extends Message> implements AggregateFunction<T, Long, AggregateOuterClass.Aggregate> {
#Override
public Long createAccumulator() {
return 0L;
}
#Override
public Long add(T event, Long accumulator) {
return accumulator + 1L;
}
#Override
public AggregateOuterClass.Aggregate getResult(Long accumulator) {
return AggregateOuterClass.Aggregate.newBuilder().setVolume(accumulator).build();
}
#Override
public Long merge(Long accumulator1, Long accumulator2) {
return accumulator1 + accumulator2;
}
}
and used here
DataStream<AggregateOuterClass.Aggregate> aggregatedStream = someEntryStream
.windowAll(TumblingEventTimeWindows.of(Time.seconds(5)))
.aggregate(new BasicCounter<MonitorOuterClass.Monitor>());
TimeCharacteristics are ingestionTime
I read about a TiggerFunction which might detect if the aggregated Stream has received an event after x time but i am not sure if that is the right way to do it.
I expected the aggregation to happen even is there would be no events at all within the window. Maybe there is a setting i am not aware of?
Thx for any hints.
I chose Option 1 as suggested by #David-Anderson:
Here is my Event Generator:
public class EmptyEventSource implements SourceFunction<MonitorOuterClass.Monitor> {
private volatile boolean isRunning = true;
private final long delayPerRecordMillis;
public EmptyEventSource(long delayPerRecordMillis){
this.delayPerRecordMillis = delayPerRecordMillis;
}
#Override
public void run(SourceContext<MonitorOuterClass.Monitor> sourceContext) throws Exception {
while (isRunning) {
sourceContext.collect(MonitorOuterClass.Monitor.newBuilder().build());
if (delayPerRecordMillis > 0) {
Thread.sleep(delayPerRecordMillis);
}
}
}
#Override
public void cancel() {
isRunning = false;
}
}
and my adjusted AggregateFunction:
public class BasicCounter<T extends Message> implements AggregateFunction<T, Long, AggregateOuterClass.Aggregate> {
#Override
public Long createAccumulator() {
return 0L;
}
#Override
public Long add(T event, Long accumulator) {
if(((MonitorOuterClass.Monitor)event).equals(MonitorOuterClass.Monitor.newBuilder().build())) {
return accumulator;
}
return accumulator + 1L;
}
#Override
public AggregateOuterClass.Aggregate getResult(Long accumulator) {
AggregateOuterClass.Aggregate newAggregate = AggregateOuterClass.Aggregate.newBuilder().setVolume(accumulator).build();
return newAggregate;
}
#Override
public Long merge(Long accumulator1, Long accumulator2) {
return accumulator1 + accumulator2;
}
}
Used them Like this:
DataStream<MonitorOuterClass.Monitor> someEntryStream = env.addSource(currentConsumer);
DataStream<MonitorOuterClass.Monitor> triggerStream = env.addSource(new EmptyEventSource(delayPerRecordMillis));
DataStream<AggregateOuterClass.Aggregate> aggregatedStream = someEntryStream
.union(triggerStream)
.windowAll(TumblingProcessingTimeWindows.of(Time.seconds(5)))
.aggregate(new BasicCounter<MonitorOuterClass.Monitor>());
Flink's windows are created lazily, when the first event is assigned to a window. Thus empty windows do not exist, and can't produce results.
In general there are three ways to workaround this issue:
Put something in front of the window that adds events to the stream, ensuring that every window has something in it, and then modify your window processing to ignore these special events when computing their results.
Use a GlobalWindow along with a custom Trigger that uses processing time timers to trigger the window (with no events flowing, the watermark won't advance, and event time timers won't fire until more events arrive).
Don't use the window API, and implement your own windowing with a ProcessFunction instead. But here you'll still face the issue of needing to use processing time timers.
Update:
Having now made an effort to implement an example of option 2, I cannot recommend it. The issue is that even with a custom Trigger, the ProcessAllWindowFunction will not be called if the window is empty, so it is necessary to always keep at least one element in the GlobalWindow. This appears then to require implementing a rather hacky Evictor and ProcessAllWindowFunction that collaborate to retain and ignore a special element in the window -- and you also have to somehow get that element into the window in the first place.
If you're going to do something hacky, option 1 appears to be much simpler.

How do I tell Camel that I will end the message processing myself

I am writing a component (an endpoint) that will receive the Camel Exchange like this:
from("file|activemq|whatever").to(myEndpoint);
Upon receiving, I want it to pass the exchange to a set of subroutines, which may work asynchronously, and which will eventually decide that they have finished, possibly composed a response in an Out message of the Exchange. All may happen outside the Camel Context, I am working only with the Exchange object.
Then my subroutines should invoke something that will tell Camel that it should propagate the response back, do other stuff as per the source and middle components requirements (for example, if it is a file:/, rename a file) and consider the routing ow this Exchange completed.
I was thinking that I would invoke the Exchange's Uint of Work done method.
Unfortunately I am noticing that Camel still tries to end the exchange by itself too, in wrong time and state. For example, for file source, it fails to rename the file which already has been removed.
Here is some of my code:
Here I define an endpoint:
_proceeder = new DefaultEndpoint() {
private final String _defaultUri = "rex:producer-" + UUID.randomUUID().toString();
#Override
protected String createEndpointUri() {
return _defaultUri;
}
#Override
public Producer createProducer() throws Exception {
return new DefaultAsyncProducer(this) {
#Override
public boolean process(final Exchange exchange1, final AsyncCallback callback) {
final ExchangeWrapper exchange = new ExchangeWrapper(_uri, exchange1, MessageSystem.this);
_LOG.debug("Got input for {}. Processing...", _uri);
exchange._taken(); // 1. all subsequent will increase by 1
/// some majick....
final boolean done = exchange._released(); // if all were released immediately, itll be 0 and sent back now. otherwise the last to release will send it back.
if (done) {
_LOG.debug("Processed input for {} synchronously", _uri);
//callback.done(true);
} else {
_LOG.debug("Processed input for {} asynchronously, awaiting response", _uri);
//exchange1.addOnCompletion(new Synchronization() {
// #Override
// public void onComplete(Exchange exchange) {
// onFailure(exchange);
// }
//
// #Override
// public void onFailure(Exchange exchange) {
// callback.done(false);
// }
//});
}
return done;
}
};
}
#Override
public Consumer createConsumer(Processor processor) throws Exception {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public boolean isSingleton() {
return true;
}
};
_proceeder.setCamelContext(context);
Needless to say that I don't understand why I am given an AsyncCallback in my DefaultAsyncProducer.process() method; regardless of me calling its done() method, the system doesn't see this and still ends the exchange by itself once more. But it is not the question.
here is the ExchangeWrapper _released and _done methods:
private void _done() throws Exception {
UnitOfWork uow = _exchange.getUnitOfWork();
uow.done(_exchange);
//try{
// uow.stop();
//}catch(Exception e){
//
//}
_exchange.setUnitOfWork(null);
}
private boolean _released() {
final boolean ret;
final int cnt;
final int trancnt;
synchronized (_exchange) {
cnt = _exchange.getProperty("rex.takenCount", Integer.class) - 1;
_exchange.setProperty("rex.takenCount", cnt);
trancnt = _exchange.getProperty("rex.takenAsTransient", Integer.class);
}
if (_LOG.isDebugEnabled()) {
_LOG.debug("Input for {} released. {} times left, {} transient", new Object[]{_exchange.getProperty("rex.uri", String.class), cnt, trancnt});
}
if (cnt <= 0 || cnt <= trancnt) {
if (_LOG.isDebugEnabled()) {
_LOG.debug("Message for {} is processed by all non-transient receivers. Setting done...", new Object[]{_exchange.getProperty("rex.uri", String.class)});
}
_done();
ret = true;
if (_LOG.isDebugEnabled()) {
_LOG.debug("Message for {} is set done", new Object[]{_exchange.getProperty("rex.uri", String.class)});
}
} else {
ret = false;
}
return ret;
}
So basically I wrap the Exchange to keep state and decide when the processing should be stopped.
While digging into the Camel internals I've seen some similar counters that keep track of how many times the Exchange has been taken for processing, but I'd like to be in control, thus my own wrapper.
So what should I call instead of
_exchange.getUnitOfWork().done(_exchange);
to tell the Camel Internal Processor and others that there is no need to mark the exchange done because I am doing it?
My latest finding is to call uow.stop(); so that it clears all the 'after' processors etc, but I suddenly understood that I may try and hack Camel myself for a long time, but it's better to ask people who know exactly what to do without trying and guessing.
These are the examples of my Routes:
RouteBuilder rb = new RouteBuilder(_context) {
#Override
public void configure() throws Exception {
if (_tokenizer != null) {
from(_uri).split().method(_tokenizer, "tokenizeReader").streaming().to(_proceeder);
} else {
from(_uri).to(_proceeder);
}
}
};
If I could avoid building routes, instantiating endpoints and producers, and employ standalone processors, I'd happily do, but I don't want to ditch what the marvelous Camel project has to offer in terms of splitting, streaming, marshalling etc etc; and all of this seems to be built around routes.
May be I am not clear with what are you trying to achieve with this, but let me try.
Upon receiving, I want it to pass the exchange to a set of
subroutines, which may work asynchronously, and which will eventually
decide that they have finished
So for this you can write a processor and configure it at the end of your route .Within your processor you can use a thread pool, submit to it the subroutine tasks, wait for their completion and decide if you want to change the message body ( correct way explained here with a good diagram explaining flow of an exchange through a route) and camel will automatically take care of returning the response to the caller of the route based on exchange pattern. For example in your case if the route begins from file/activemq route then it is event based/one way exchange and no response will be sent to the caller as there is no caller client as such. It will be just an event which will initiate the exchange.
Update :
For using the async processing feature in camel for enhanced scalability take a look at this example with code from the highly recommended Camel in Action book

IWeakEventListener.ReceiveWeakEvent() called multiple times when PropertyChanged(null) is called on source object

I'm using the PropertyObserver class in my code to avoid doing string comparisons in PropertyChanged event handling and factor out the handling of null or string.Empty as its argument (Which indicates that all properties of an object has changed).
This class uses PropertyChangedEventManager to register callbacks in the target object and implements IWeakEventListener to respond every time PropertyChanged event is invoked on the source object.
But during the creation of a unit test I found out that the IWeakEventListener.ReceiveWeakEvent() is called N number of times, with N as the number of the registered callbacks. This only occurs when null or string.Empty is specified, not when a valid property name is given in the PropertyChanged event.
Does anyone knows why this is happening and how to fix it? My goal is to do a foreach of the registered handlers ONE time when null is given, so I can update my target object by getting all the properties of the source object. But when ReceiveWeakEvent() is called N times then the foreach will be repeated N times!
To illustrate it, the following is a simplified version of the PropertyObserver class and the source class (I'm using MVVM Light's ObservableObject for INotifyPropertyChanged implementation):
public class PropertyObserver : IWeakEventListener {
public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e) {
if (managerType == typeof(PropertyChangedEventManager)) {
string propertyName = ((PropertyChangedEventArgs)e).PropertyName;
if (string.IsNullOrEmpty(propertyName)) {
Console.WriteLine ("Foreach registered handlers and invoke one by one");
} else {
Console.WriteLine ("Invoke handler for property {0}", propertyName);
}
return true;
}
return false;
}
}
public class ViewModel : ObservableObject {
private int mProp1;
private int mProp2;
public int Prop1 {
get { return mProp1; }
set {
mProp1 = value;
RaisePropertyChanged("Prop1");
}
}
public int Prop2 {
get { return mProp2; }
set {
mProp2 = value;
RaisePropertyChanged("Prop2");
}
}
public void RaiseAllPropertyChanged() {
RaisePropertyChanged(null);
}
}
And in a console app's Main we can call them like so:
var vm = new ViewModel();
var obs = new PropertyObserver();
// Normally this is done inside the PropertyObserver class.
PropertyChangedEventManager.AddListener(vm, obs, "Prop1");
PropertyChangedEventManager.AddListener(vm, obs, "Prop2");
vm.Prop1 = 1; // Results in a console line "Invoke handler for property Prop1"
vm.Prop2 = 2; // Results in a console line "Invoke handler for property Prop2"
// Results in two console lines: "Foreach registered handlers and invoke one by one", expected is only 1!
vm.RaiseAllPropertyChanged();
Okay, I didn't understand the AddListener() method before. I only need to register a listener once:
PropertyChangedEventManager.AddListener(vm, obs, string.Empty);
to listen to all PropertyChanged events of a source object. Doing this will produce the correct working of the PropertyObserver class:
vm.Prop1 = 1; // "Invoke handler for property Prop1"
vm.Prop2 = 2; // "Invoke handler for property Prop2"
// Now results in one console line "Foreach registered handlers and invoke one by one"
vm.RaisePropertyChanged();
Each registered listener with non-empty third argument (the property name) will respond to only the specified property name and null or string.Empty. So that's why the foreach was invoked twice on the original code.

Custom Message Box Advice

Well I'm using a Window as my custom message box with a couple of controls which are displayed/populated with text depending on which constructor is called.
I have a defined event, which is subscribed to via the original class, this fires once the button has been clicked.
However I can't see how to use this effectively, preferably I'd like to return a bool whether Yes or No was clicked, however obviously my code will carry on executing, hence the method which is subscibed to the button click. Below is some example code to make the issue clearer.
Message Box Window
public partial class CustomMessageBox : Window
{
public delegate void MessageBoxHandler(object sender, EventArgs e);
public event MessageBoxHandler MessageBoxEvent;
public CustomMessageBox()
{
InitializeComponent();
}
public CustomMessageBox(string message)
{
InitializeComponent();
this.txtdescription.Text = message;
}
public CustomMessageBox(string message, string title, string firstBtnText)
{
InitializeComponent();
this.lbltitle.Content = title;
this.txtdescription.Text = message;
this.btnstart.Content = firstBtnText;
}
}
public static class MessageBoxButtonClick
{
public static bool Yes { get; set; }
public static bool No { get; set; }
public static bool Cancel { get; set; }
}
Window Which Instantiates the MessageBox Window
private void StartProcess_Click(object sender, System.Windows.RoutedEventArgs e)
{
foreach (var result in results)
{
if(result.ToBeProcessed)
_validResults.Add(new ToBeProcessed(result.Uri, result.Links));
}
_msgbox = new CustomMessageBox("Each Uri's backlinks will now be collected from Yahoo and filtered, finally each link will be visited and parsed. The operation is undertaken in this manner to avoid temporary IP Blocks from Yahoo's servers.", "Just a FYI", "OK");
_msgbox.MessageBoxEvent += (MessageBoxHandler);
if (_msgBoxProceed)
{
_msgbox.Close();
Yahoo yahoo = new Yahoo();
yahoo.Status.Sending += (StatusChange);
//What I'd like to happen here is the code simply stop, like it does when calling a messagebox is winforms
//e.g.
// if(ProceedClicked == true)
// do stuff
// yahoo.ScrapeYahoo(_validResults[Cycle].Uri, _validResults[Cycle].LinkNumber);
//Cycle++;
}
else
{
_msgbox.Close();
}
}
private void MessageBoxHandler(object sender, EventArgs e)
{
if (MessageBoxButtonClick.Yes)
{
ProceedClicked = true;
}
else
{
ProceedClicked = false;
}
}
Hopefully that makes it clear enough, I can't put any execution code ie call a certain method due to using it multiple times throughout my application.
Very hard to understand what the problem exactly is. Also the code you wrote here, doesn't seemt to have any calls, that would actually show the CustomMessageBoxWindow.
But I'll take a stab at this...
First of all, am I right in guessing that in your main Window you want your code to wait at if(_msgBoxProceed) until the user actually presses a button in your CustomMessageBoxWindow (currently it just shows the message box and continues executing the next statements)?
If so then I'm guessing you are showing your message box window with the Show() method. Use ShowDialog() instead. That will cause code execution to stop, until the message box gets closed.
If you don't want to use a modal dialog then there are two options. Either use thread syncrhonization objects (eg AutoResetEvent) or set up a new event for when the message box closes and continue your code execution in the closed event handler (in StartProcess_Click the last line would be a call to _msgBox.Show() and everything from if(_msgBoxProceed) would be in the closed event handler).

Resources