I'd like to give error queues names in EasyNetQ based on the name of the queue that originated the error. For example, all faulted messages from QueueA would go to QueueA.Error; QueueB messages would be redirected to QueueB.Error, and so on.
However, the ErrorQueueNamingConvention doesn't receive a MessageReceivedInfo parameter, as ErrorExchangeNamingConvention does, and so I cannot know what is the name of the original queue. Is there any way of getting it or any workarounds?
Thanks
You can do this by setting the ErrorQueueNamingConvention on the IBus. So it's done at the bus level, not the individual message level. I name my error queues to match the queue to which the consumer is bound (which I define in configuration). When errors occur while processing messages from queue A, for example, those errors will be routed to queue A_Errors. Here's a sample:
var errorExchangeName = _configuration.ExchangeName + "_Errors";
var errorQueueName = _configuration.ListenerQueueName + "_Errors";
var conventions = _bus.Advanced.Container.Resolve<IConventions>();
conventions.ErrorExchangeNamingConvention = info => errorExchangeName;
conventions.ErrorQueueNamingConvention = () => errorQueueName;
You can see in the following code fragment from https://github.com/EasyNetQ/EasyNetQ/blob/master/Source/EasyNetQ/Consumer/DefaultConsumerErrorStrategy.cs how EasyNetQ uses your ErrorQueueNamingConvention to bind to the error queue so it can forward messages to it:
private string DeclareErrorExchangeAndBindToDefaultErrorQueue(IModel model, ConsumerExecutionContext context)
{
var originalRoutingKey = context.Info.RoutingKey;
return errorExchanges.GetOrAdd(originalRoutingKey, _ =>
{
var exchangeName = conventions.ErrorExchangeNamingConvention(context.Info);
model.ExchangeDeclare(exchangeName, ExchangeType.Direct, durable: true);
model.QueueBind(conventions.ErrorQueueNamingConvention(), exchangeName, originalRoutingKey);
return exchangeName;
});
}
So, if you need even more control then you can override this DefaultConsumerErrorStrategy as well. There you can get at the context you are looking for, though I don't think you need it to get the behavior you are looking for.
Also see this answer.
Related
I'm following this tutorial to implement object tracking on iOS 11. I'm able to track objects perfectly, until a certain point, then this error appears in the console.
Throws: Error Domain=com.apple.vis Code=9 "Internal error: Exceeded maximum allowed number of Trackers for a tracker type: VNObjectTrackerType" UserInfo={NSLocalizedDescription=Internal error: Exceeded maximum allowed number of Trackers for a tracker type: VNObjectTrackerType}
Am I using the API incorrectly, or perhaps Vision has trouble handling too many consecutive object tracking tasks? Curious if anyone has insight into why this is happening.
It appears that you hit the limit on the number of trackers that can be active in the system. First thing to note is that a new tracker is created every time a new observation, with new -uuid property is used. You should be recycling the initial observation you use when you started the tracker, until you no longer want to use it, by feeding what you got from “results” for time T into the subsequent request you make for time T+1. When you no longer want to use that tracker (maybe the confidence score gets too low), there is a “lastFrame” property that can be set, which lets the Vision framework know that you are done with that tracker. Trackers also get released when the sequence request handler is released.
To track the rectangle you feed consequent observations to the same VNSequenceRequestHandler instance, say, handler. When the rectangle is lost, i.e. the new observation is nil in your handler function / callback, or you are getting some other tracking error, just re-instantiate the handler and continue, e.g. (sample code to show the idea):
private var handler = VNSequenceRequestHandler()
// <...>
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard
let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer),
let lastObservation = self.lastObservation
else {
self.handler = VNSequenceRequestHandler()
return
}
let request = VNTrackObjectRequest(detectedObjectObservation: lastObservation, completionHandler: self.handleVisionRequestUpdate)
request.trackingLevel = .accurate
do {
try self.handler.perform([request], on: pixelBuffer)
} catch {
print("Throws: \(error)")
}
}
Note that handler is var, not a constant.
Also, you may re-instantiate the handler in actual handler function (like func handleVisionRequestUpdate(_ request: VNRequest, error: Error?)) in case new observation object is invalid.
My problem with this was that I had a function that called perform... on the same VNSequenceRequestHandler that the tracking was also calling perform on, because of that I was processing too many try self.visionSequenceHandler.perform(trackRequests, on: ciimage) concurrently. Make sure the VNSequenceRequestHandler is not getting hit at the same time by multiple performs....
I am using the ExecuteQueryAsync on multiple lists to fill data into a List<ListItemCollection>. Once all the responses are received, I bind the data onto my Silverlight Application.
ExecuteQueryAsync could ideally go into success or failure. I basically keep track of the total number responses received on both Success and Failure and once the count received matches with the total requests. I show a wait icon till all the responses are received and the data is bound to the application. Now the problem is that, for example, I make 12 requests, I receive only 10 or 11 responses back. I don't seem to understand why I dont receive the response for the last few requests. I neither goes to success not to failure.
Is someone facing this issue? Could you help me understand what is causing this issue and why the response is neither received as a success nor a failure. If I perform the same operation, it works. This issue keeps happening every now and then and I am not sure how to fix this issue.
var requestCount = 0;
var responseCount = 0;
List<ListItemCollection>() bindingData;
public function getData(){
showWaitIcon();
//Some Code here to form the CAML query
bindingData = new List<ListItemCollection>();
for(int i=0; i<10; i++){
//Some Code here to create the Client Context to query each Document Library or List
clientContext.RequestTimeout = -1;
clientContext.Load(clientContext.Web);
ListItemCollection _lstItems;
clientContext.Load(_lstItems);
clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
requestCount++;
}
}
private void onQuerySucceeded(object sender, ClientRequestSucceededEventArgs args)
{
responseCount++;
this.Dispatcher.BeginInvoke(BindData);
}
private void onQueryFailed(object sender, ClientRequestFailedEventArgs args)
{
responseCount++;
this.Dispatcher.BeginInvoke(BindData);
}
private function BindData(){
if(requestCount == responseCount() {
hideWaitIcon();
bindToSilverlightView(bindingData);
}
}
The most probable cause I can think of, without looking through your code, is that you have a synchronization issue, that is, two or more of your requests are receiving the result at nearly the exact same time and trying to modify the variable where you keep track of the number of answered requests. You may need to use a "lock" or similar structure to make sure that block of code is not accessed by two threads at once.
I am trying to implement more advanced Apache Camel error handling:
in case if there are too many pending retries then stop processing at all and log all collected exceptions somewhere.
First part (stop on too many retries) is already implemented by following helper method, that gets size of retry queue and I just stop context if queue is over some limit:
static Long getToRetryTaskCount(CamelContext context) {
Long retryTaskCount = null;
ScheduledExecutorService errorHandlerExecutor = context.getErrorHandlerExecutorService();
if (errorHandlerExecutor instanceof SizedScheduledExecutorService)
{
SizedScheduledExecutorService svc = (SizedScheduledExecutorService) errorHandlerExecutor;
ScheduledThreadPoolExecutor executor = svc.getScheduledThreadPoolExecutor();
BlockingQueue<Runnable> queue = executor.getQueue();
retryTaskCount = (long) queue.size();
}
return retryTaskCount;
}
But this code smells to me and I don't like it and also I don't see here any way to collect the exceptions caused all this retries.
There is also a new control bus component in camel 2.11 which could do what you want (source)
template.sendBody("controlbus:route?routeId=foo&action=stop", null);
I wouldn't try to shutdown the CamelContext, just the route in question...that way the rest of your app can still function, you can get route stats and view/move messages to alternate queues, etc.
see https://camel.apache.org/how-can-i-stop-a-route-from-a-route.html
I have a problem using "fire()" with a GWT RequestFactory after I've used it to unfreeze and edit a proxy.
If I have two request factory objects and their associated contexts like this:
private SyntheticRequest req1 = requestFactory.someRequest();
private Request<xProxy> sendRequest1 = req1.something();
private SyntheticRequest req2 = requestFactory.someRequest();
private Request<xProxy> sendRequest2 = req2.something();
using "fire()" on the first request works fine:
sendRequest1.fire(new Receiver<xProxy>() {
#Override
public void onSuccess(xProxy response) {
...
if (somethingIsTrue){
xProxy x = req2.edit(response); //<-- **I think this causes a problem later, although the proxy "x" works as expected here.**
x.setSomething("something");
update();
}
});
that part runs ok because I get to the "onSuccess". But when this one runs "update()", which looks like this:
private void update(){
sendRequest2.fire(new Receiver<xProxy>(){
...onFailure...
...onSuccess...
});
}
sendRequest2 always fails, with the error
Server Error Index:0 Size:0
and I put a breakpoint in the code for the "something()" service and it never even gets to that code! There must be something about the "req2.edit()" that hurts req2 and sendRequest2, but what?
Thanks.
what is 'b'? the line xProxy x = req2.edit(b); is the first time it's mentioned? is it supposed to be xProxy x = req2.edit(response);
Anyway.. that is not the problem..
'Server Error' indicates that RequestFactory caught an exception during the processing of a request, server-side. Something (but maybe not something()) is throwing an IndexOutOfBounds exception.
If you have a look at RequestFactoryServlet.java (which you can replace with your own very easily btw) you can see it setting up a try catch block that catches all exceptions when processing a request. It passes them to 'DefaultExceptionHandler' which wraps them in a ServerFailure, and that gets returned to you GWT code as an onFailure() call.
An easy way to find where the exception is being thrown is set a breakpoint on IndexOutOfBoundsException, making sure to catch 'caught' exceptions as well as uncaught.
I am trying to reuse some .NET code that performs some calls to a data-access-layer type service. I have managed to package up both the input to the method and the output from the method, but unfortunately the service is called from inside code that I really don't want to rewrite in order to be asynchronous.
Unfortunately, the webservice code generated in Silverlight only produces asynchronous methods, so I was wondering if anyone had working code that managed to work around this?
Note: I don't need to execute the main code path here on the UI thread, but the code in question will expect that calls it makes to the data access layers are synchronous in nature, but the entire job can be mainly executing on a background thread.
I tried the recipe found here: The Easy Way To Synchronously Call WCF Services In Silverlight, but unfortunately it times out and never completes the call.
Or rather, what seems to happen is that the completed event handler is called, but only after the method returns. I am suspecting that the event handler is called from a dispatcher or similar, and since I'm blocking the main thread here, it never completes until the code is actually back into the GUI loop.
Or something like that.
Here's my own version that I wrote before I found the above recipe, but it suffers from the same problem:
public static object ExecuteRequestOnServer(Type dalInterfaceType, string methodName, object[] arguments)
{
string securityToken = "DUMMYTOKEN";
string input = "DUMMYINPUT";
object result = null;
Exception resultException = null;
object evtLock = new object();
var evt = new System.Threading.ManualResetEvent(false);
try
{
var client = new MinGatServices.DataAccessLayerServiceSoapClient();
client.ExecuteRequestCompleted += (s, e) =>
{
resultException = e.Error;
result = e.Result;
lock (evtLock)
{
if (evt != null)
evt.Set();
}
};
client.ExecuteRequestAsync(securityToken, input);
try
{
var didComplete = evt.WaitOne(10000);
if (!didComplete)
throw new TimeoutException("A data access layer web service request timed out (" + dalInterfaceType.Name + "." + methodName + ")");
}
finally
{
client.CloseAsync();
}
}
finally
{
lock (evtLock)
{
evt.Close();
evt = null;
}
}
if (resultException != null)
throw resultException;
else
return result;
}
Basically, both recipes does this:
Set up a ManualResetEvent
Hook into the Completed event
The event handler grabs the result from the service call, and signals the event
The main thread now starts the web service call asynchronously
It then waits for the event to become signalled
However, the event handler is not called until the method above has returned, hence my code that checks for evt != null and such, to avoid TargetInvocationException from killing my program after the method has timed out.
Does anyone know:
... if it is possible at all in Silverlight 3
... what I have done wrong above?
I suspect that the MinGatServices thingy is trying to be helpful by ensuring the ExecuteRequestCompleted is dispatched on the main UI thread.
I also suspect that your code is already executing on the main UI thread which you have blocked. Never block the UI thread in Silverlight, if you need to block the UI use something like the BusyIndicator control.
The knee-jerk answer is "code asynchronously" but that doesn't satisfy your question's requirement.
One possible solution that may be less troublesome is to start the whole chunk of code from whatever user action invokes it on a different thread, using say the BackgroundWorker.
Of course the MinGatServices might be ensuring the callback occurs on the same thread that executed ExecuteRequestAsync in which case you'll need to get that to run on a different thread (jumping back to the UI thread would be acceptable):-
Deployment.Current.Dispatcher.BeginInvoke(() => client.ExecuteRequestAsync(securityToken, input));