Hystrix: cannot trip circuit breaker - hystrix

Assuming i use the default Hystrix configurations:
CircuitBreakerRequestVolumeThreshold=20
CircuitBreakerErrorThresholdPercentage=50
MetricsRollingStatisticalWindowInMilliseconds=10000ms
I assume this means that within a 10 sec window, the circuit will break if there are 10 handled exceptions within 20 consecutive requests.
I have a class called MyCommand which extends HystrixCommand. I create 20 objects of it and call execute on each sequentially. But I don't seem to trip the circuit because it never goes into my getFallback method. I expected the 20th execute to trip the circuit. Where am i going wrong?
int i=0;
public MyObject run() throws Exception {
i++;
try {
throw new Exception("Handled exception "+i);
} catch (Exception e) {
System.out.print("Catch "+i);
}
return null;
}

If you handle the exceptions within the command then the circuit breaker will not open. In your run method do not catch the exception.

Related

CEP - Pattern not executed after adding Window

//Creating a window of ten items
WindowedStream<ObservationEvent,Tuple,GlobalWindow> windowStream = inputStream.keyBy("rackId").countWindow(10);
// Applying a Window Function , adding some custom evaluating all the values in the window
DataStream<ObservationEvent> inactivityStream = windowStream.apply(new WindowFunction<ObservationEvent, ObservationEvent , Tuple , GlobalWindow>() {
#Override
public void apply(Tuple tuple, GlobalWindow timeWindow, Iterable<ObservationEvent> itr, Collector<ObservationEvent> out)
//custom evaluation logic
out.collect(new ObservationEvent(1,"temperature", "stable"));
}
});
//Defining Simple CEP Pattern
Pattern<ObservationEvent, ?> inactivityPattern = Pattern.ObservationEvent>begin("first")
.subtype(ObservationEvent.class)
.where(new FilterFunction<ObservationEvent>() {
#Override
public boolean filter(ObservationEvent arg0) throws Exception {
System.out.println( arg0 ); //This function is not at all called
return false;
}
});
PatternStream<ObservationEvent> inactivityCEP = CEP.pattern(inactivityStream.keyBy("rackId"), inactivityPattern);
When I run this code, the filter function inside the where clause is not at all getting called.
I have printed the inactivityStream.print() and I can see the matching value.
Now, when I plug in the inputStream directly without applying a window. The pattern is matching
I printed inputStream and WindowedStream and I can see they both send similar kind of data.
What am I missing
The FilterFunction should be getting called eventually but you are going to have to wait for 10 events for the SAME key before you see your FilterFunction called for the first time. Could it be that you are just not waiting long enough in your windowing test?
Keep in mind that if you have many unique keys this implies you will have to wait well more than 10 times as long in the window test before you'll see your filter function called.

Tomcat executor with runnable while(true) loop is only run once. Why?

I am trying to implement a javax.mail.event.MessageCountListener in Tomcat. When I start the application the contextInitialized method seems to run and the mailbox is read. However, I see the log message "Idling" only once. I would expect that it would idle constantly and invoke the AnalyzerService() when an email is received or deleted.
Update: Found that the idle() method is not returning. It runs untill com.sun.mail.iap.ResponseInputStream.readResponse(ByteArray ba) method where it runs into a while loop where it never gets out.
Am I misusing the idle() method for something I should not do? Is this a bug in com.sun.mail.iap package?
The AnalyzerContextListener.java:
import com.sun.mail.imap.IMAPStore;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.event.MessageCountListener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class AnalyzerContextListener implements ServletContextListener {
private ExecutorService executorService;
private final String username = "myemail#gmail.com";
private final String password = "mypassword";
private final String mailhost = "imap.gmail.com";
private final String foldername = "INBOX";
#Override
public void contextInitialized(ServletContextEvent sce) {
final ServletContext servletContext = sce.getServletContext();
executorService = Executors.newFixedThreadPool(3);
Session session = Session.getInstance(new Properties());
try {
final IMAPStore store = (IMAPStore) session.getStore("imaps");
store.connect(mailhost, username, password);
final Folder folder = store.getFolder(foldername);
if (folder == null) {
servletContext.log("Folder in mailbox bestaat niet.");
return;
}
folder.open(Folder.READ_ONLY);
MessageCountListener countListener = new AnalyzerService();
folder.addMessageCountListener(countListener);
Runnable runnable = new Runnable() {
#Override
public void run() {
while (true) {
try {
servletContext.log("Aantal berichten in folder: " + folder.getMessageCount());
servletContext.log("Idling");
store.idle();
} catch (MessagingException ex) {
servletContext.log(ex.getMessage());
return;
}
}
}
};
executorService.execute(runnable);
servletContext.log("Executorservice gestart");
} catch (MessagingException ex) {
servletContext.log(ex.getMessage());
}
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
sce.getServletContext().log("Context wordt vernietigd");
executorService.shutdown();
sce.getServletContext().log("Executorservice gestopt");
}
}
The AnalyzerService.java:
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.event.MessageCountEvent;
import javax.mail.event.MessageCountListener;
class AnalyzerService implements MessageCountListener {
public AnalyzerService() {
}
#Override
public void messagesAdded(MessageCountEvent event) {
Message[] addedMessages = event.getMessages();
for (Message message : addedMessages) {
try {
System.out.println(message.getSubject());
} catch (MessagingException ex) {
System.out.println(ex.getMessage());
}
}
}
#Override
public void messagesRemoved(MessageCountEvent event) {
Message[] removedMessages = event.getMessages();
for (Message message : removedMessages) {
try {
System.out.println(message.getSubject());
} catch (MessagingException ex) {
System.out.println(ex.getMessage());
}
}
}
}
while (true) {
try {
servletContext.log("Aantal berichten in folder: " + folder.getMessageCount());
servletContext.log("Idling");
store.idle();
} catch (MessagingException ex) {
servletContext.log(ex.getMessage());
return;
}
}
has exactly 2 3 possibilities to end earlier than never run only once.
The loop actually ends either:
Through the explicit return in case of a MessagingException. Look at your logs, there either a message or something strange like "null". Consider using a proper stacktrace log (.log(String message, Throwable throwable)) since Exception#getMessage() is often empty or not telling you much.
Through any unchecked exception. You should notice that in some log though since uncaught exceptions via executorService.execute should invoke the nearest uncaught exeption handler which is generally bad. See Choose between ExecutorService's submit and ExecutorService's execute
The loop stops executing after it logs "Idling"
store.idle() never returns. (every other line of code could do that theoretically as well, e.g. the folder.getMessageCount() call in a 2nd iteration but that's very unlikely)
Regarding No 3 - the documentation
Use the IMAP IDLE command (see RFC 2177), if supported by the server, to enter idle mode so that the server can send unsolicited notifications without the need for the client to constantly poll the server. Use a ConnectionListener to be notified of events. When another thread (e.g., the listener thread) needs to issue an IMAP comand for this Store, the idle mode will be terminated and this method will return. Typically the caller will invoke this method in a loop.
If the mail.imap.enableimapevents property is set, notifications received while the IDLE command is active will be delivered to ConnectionListeners as events with a type of IMAPStore.RESPONSE. The event's message will be the raw IMAP response string. Note that most IMAP servers will not deliver any events when using the IDLE command on a connection with no mailbox selected (i.e., this method). In most cases you'll want to use the idle method on IMAPFolder.
That sounds like this method is not designed to return any time soon. In your case never since you don't issue any commands towards the server after you enter idle. Besides that
folder.idle() could be what you should actually do
I guess the documentation is wrong, however ConnectionListener and MessageCountListener are two different things.

How to get Json Array to work inside Asyntask - Android [duplicate]

This question already has an answer here:
How to put Json inside asynctask - Android
(1 answer)
Closed 9 years ago.
I have an Asynctask that uses a Json function in the doInBackground part. The function collects an array of comments and places them into a variable called KEY_COMMENTS. In the onPreExecute it places the comments into a textView using a for loop to select each comment individually. The problem is that its not selecting each comment it will only select one. If I set the loop to go for more than 1 time it will crash the app. Here is my code,
class loadComments extends AsyncTask<JSONObject, String, JSONObject> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
protected JSONObject doInBackground(JSONObject... params) {
//do your work here
JSONObject json2 = CollectComments.collectComments(usernameforcomments, offsetNumber);
return json2;
}
#Override
protected void onPostExecute(JSONObject json2) {
try {
if (json2.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res2 = json2.getString(KEY_SUCCESS);
if(Integer.parseInt(res2) == 1){
JSONArray array = json2.getJSONArray(KEY_COMMENT);
for(int i = 0; i < 2; i++) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
commentBox.setBackgroundResource(R.drawable.comment_box_bg);
layoutParams.setMargins(0, 10, 0, 10);
commentBox.setPadding(0,0,0,10);
commentBox.setOrientation(LinearLayout.VERTICAL);
linear.addView(commentBox, layoutParams);
commentBoxHeader.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
commentBoxHeader.setBackgroundResource(R.drawable.comment_box_bg);
commentBoxHeader.setBackgroundResource(R.drawable.comment_box_header);
commentBox.addView(commentBoxHeader);
commentView.setText(array.getString(i));
LinearLayout.LayoutParams commentViewParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
commentViewParams.setMargins(20, 10, 20, 20);
commentView.setBackgroundResource(R.drawable.comment_bg);
commentView.setTextColor(getResources().getColor(R.color.black));
commentBox.addView(commentView, commentViewParams);
}
}//end if key is == 1
else{
// Error in registration
registerErrorMsg.setText(json2.getString(KEY_ERROR_MSG));
}//end else
}//end if
} //end try
catch (JSONException e) {
e.printStackTrace();
}//end catch
}
}
doInBackGround : method is used as a Thread !
onPostExecute : acts as a UI Thread !
So try to put your any-long running code in , doInBackGround method !
When an asynchronous task is executed, the task goes through 4 steps:
From the Docs :
onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.

Error while setting volume on SoundEffectInstance

I am seeing an error be reported quite frequently in my application. I know where it is happening, I just don't know why. The app plays sound effects (not background music), I am using Xna.Audio and I have a timer to call FrameworkDispatcher.Update() in regular intervals. I am using SoundEffect.CreateInstance so I can I have the sound effect loop. It looks like an error happens when changing the volume. I don't know WHY though. Are there known instances when this can fail?
Function ::: Offset
xxx_RaiseException ::: 32
WatsonUnhandledManagedException ::: 300
Dbg_NotifyManagedException ::: 136
FirstPassException ::: 1044
TransitionStub ::: 0
Microsoft.Xna.Framework.Helpers.ThrowExceptionFromErrorCode ::: 76
Microsoft.Xna.Framework.Audio.SoundEffectInstance.set_Volume ::: 232
Microsoft.Xna.Framework.Audio.SoundEffectInstance..ctor ::: 232
Microsoft.Xna.Framework.Audio.SoundEffect.CreateInstance ::: 192
AgiliTrain.PhoneyTools.Media.SoundEffectPlayer..ctor ::: 96
WildSafari.ClassicModeGame.animalVisibleTimer_Tick ::: 344
...snip....
For those asking, here is more code. The SoundEffectPlayer takes a SoundEffect, creates an instance, and kicks off the XNA FrameworkDispatcher (via the GameTimer). This code is taken from PhoneyTools, so go check out the codeplex project if you need more context. When I want to play an effect, I just new up a SoundEffectPlayer, and pass in what I want.
public class SoundEffectPlayer
{
GameTimer _xnaTimer = new GameTimer();
SoundEffectInstance _effect = null;
public float _duration;
public SoundEffectPlayer(SoundEffect effect, bool loop)
{
_effect = effect.CreateInstance();
_effect.IsLooped = loop;
_duration = (float)effect.Duration.TotalSeconds;
}
public void Play(float volume)
{
_xnaTimer.Start();
_effect.Play();
_effect.Volume = volume;
}
public void Stop()
{
_effect.Stop(true);
_xnaTimer.Stop();
}
}
public class GameTimer
{
DispatcherTimer _timer = new DispatcherTimer()
{
Interval = TimeSpan.FromMilliseconds(50),
};
public GameTimer()
{
_timer.Tick += new EventHandler(_timer_Tick);
}
void _timer_Tick(object sender, EventArgs e)
{
FrameworkDispatcher.Update();
}
public void Start()
{
if (!_timer.IsEnabled) _timer.Start();
}
public void Stop()
{
if (_timer.IsEnabled) _timer.Stop();
}
}
Trying to help out, although i don't have a valid fix...
The setter property for SoundEffectInstance is not as simple as one might think:
set
{
lock (this.voiceHandleLock)
{
if (this.IsDisposed)
{
throw new ObjectDisposedException(base.GetType().Name, FrameworkResources.ObjectDisposedException);
}
if ((value < 0f) || (value > 1f))
{
throw new ArgumentOutOfRangeException("value");
}
Helpers.ThrowExceptionFromErrorCode(SoundEffectUnsafeNativeMethods.SetVolume(this.voiceHandle, value));
this.currentVolume = value;
}
}
Basically the part we're after comes in the line before last.
If the call from SoundEffectUnsafeNativeMethods.SetVolume returns any code smaller than 0, the exception you're getting will be triggered.
Here's what's happening inside the unsafe method:
public static unsafe int modopt(IsLong) SetVolume(uint soundEffectInstanceHandle, float volume)
{
lock (SoundEffectSubsystemSyncObject)
{
if ((soundEffectInstanceHandle != 0) && (soundEffectInstanceHandle != uint.MaxValue))
{
CHandleTable* tablePtr = ?g_pTable#CHandleTable##0PAV1#A;
KernelSoundEffectInstance* instancePtr = CHandleTable.LookUp<class Microsoft::Xna::Framework::Audio::KernelSoundEffectInstance>((CHandleTable modopt(IsConst)* modopt(IsConst) modopt(IsConst)) ?g_pTable#CHandleTable##0PAV1#A, soundEffectInstanceHandle, 0);
if (instancePtr == null)
{
return -2147024809;
}
return **(((int*) instancePtr))[0x34](instancePtr, volume);
}
return -2147024809;
}
}
You can try to surround the creation of _effect.CreateInstance with try...catch and rethrow a more comprehensive and helpful exception that will contain for example, information about the SoundEffect object which you're trying to create (basically you can note down all of its field's values for inspection. (not sure that what you get from MS is only a stack trace or the actual exception messaage).
It seems that on WP7, the call to set the volume goes to some OS pointer table that does some magic behind the scenes and looks for the sound effect handle in this table.
If for some reason it is not found or something similar (don't know why, maybe we can take it with XNA developers), it will throw this exception you're getting.
I know this is not a solution but maybe this is a step in the right direction.
Generally, the exception should not be thrown for the situation you are describing, as long as you built the XNA compatibility layer as it should be (details here).
However, I noticed that you are using PhoneyTools.Media.SoundEffectPlayer - what for? It might be the cause of the problem in your situation.
Also, you seem to have ambiguous references - effect and _effect - which one are you working with when playing content?

SilverLight WCF Response does not come back in time

This code is being used to validate if an email exists in the database. The service return the values fine because it was tested with WCF Storm. In the code I am trying to call this method which return an object (validationResponse). If validationResonse has a true key I want to throw the ValidationException. What i think is happening is SL is making the call asyn and then moving one to he next line of code. How can I call a WCF method and get its reponse and act on it?
public string email
{
get
{
return _email;
}
set
{
vc.emailAddressCompleted += new EventHandler<emailAddressCompletedEventArgs>(vc_emailAddressCompleted);
vc.emailAddressAsync(value);
//Fails here with a null reference to vr (vr is declared futher up)
if (vr.isValid == false)
{
throw new ValidationException(vr.validationErrors);
}
this._email = value;
}
}
void vc_emailAddressCompleted(object sender, emailAddressCompletedEventArgs e)
{
//this never gets executed
this.vr = e.Result;
}
In silverlight all service calls are made asynchronously, in other words you can't call the service synchronously and wait for the reply. So what is happening in your code is vr is null and the exception is being thrown before the service call returns. You could change your code to something like this:
vc.emailAddressCompleted +=
new EventHandler<emailAddressCompletedEventArgs>(vc_emailAddressCompleted);
vc.emailAddressAsync(value);
//this while loop is not necessary unless you really want to wait
//until the service returns
while(vr==null)
{
//wait here or do something else until you get a return
Thread.Sleep(300);
}
//if you got here it means the service returned and no exception was thrown
void vc_emailAddressCompleted(object sender, emailAddressCompletedEventArgs e)
{
//should do some validation here
if (e.Error!=null) throw new Exception(e.Error.ToString());
vr = e.Result;
if (!vr.isValid)
{
throw new ValidationException(vr.validationErrors);
}
_email = value;
}

Resources