hang in duplex c# signalr client - signalr

somebody reported a similar issue. Its not clear what the resolution was
I have code that might invoke a response while a method is being invoked
proxy.On<string, byte[], int>("Foo", (connId, data, seq) =>
{
DoFoo();
});
DoFoo usually ends up invoking a response to the same client but on a different thread. This response call ends up hanging in its invoke.Wait() after a few messages.
If I do
proxy.On<string, byte[], int>("Foo", (connId, data, seq) =>
{
System.Threading.ThreadPool.QueueUserWorkItem((x)=>
{
DoFoo(connId, data, seq);
});
});
Things get a lot better. I have had one or 2 hangs but only under extreme load, but its still doesnt seem right. ie work 95% is better that work 20%, but 95% is not perfect
This is signalr 2.1.2

Related

Meteor.call is very slow when responding back

I am facing performance problem with Meteor.call(). I have a method on server side which gets execute within a millisecond but when I seek a response in the client side, it is taking long to get the response data inside the callback function. Is anyone experience the problem before?
I was using Meteor 1.12.1 and updated to Meteor 2.1.1 hoping to solve the problem by updating but I didn't find any difference.
Update: I am facing issue on all environment (osx, linux, windows).
For eg: This is my server code
Meteor.methods({
newEntry() {
//This method is executed within millisecond
}
})
This is my client code
function submitEntry(data) {
Meteor.call(
'newEntry',
data,
(error, res) => {
//Here I am getting the response after long wait.
},
);
}
Can somebody help me on this?
I found the solution. As per the Meteor docs.
Once the Method has finished running on the server, it sends a result message to the client with the Method ID generated in step 2, and the return value itself. The client stores this for later use, but doesn’t call the Method callback yet. If you pass the onResultReceived option to Meteor.apply, that callback is fired.
Ref: https://guide.meteor.com/methods.html#advanced-boilerplate
So if you want your call back to be triggered once the server method return the value then you can use Metor.apply method with the option onResultReceived.
Meteor.apply(
"methodName",
[...params],
{
onResultReceived: function() {
// Whatever you want to do after callback.
}
}

How to Retry RxAndroidBLE Discover Services in case of GATT error.

I am using RxAndroidBLE library for discovering services in my GATT server.
it works fine most of the time but often i get GATT error 133 (0x85) and it fails. I will like to retry for discovery of the service couple of time for a time period, say for 5 seconds.
here is the code i am trying
bleDevice = mBleClient.getBleDevice(macAddress);
subscription = bleDevice.establishConnection(false)
.flatMap(RxBleConnection::discoverServices)
.first() // Disconnect automatically after discovery
.observeOn(AndroidSchedulers.mainThread())
.doOnUnsubscribe(this::onUnsubscribe)
.compose(this.bindToLifecycle())
.retryWhen(errors -> errors.flatMap(error -> {
if (isGattError(error) {
return Observable.just(new Object());
} else {
return Observable.error(error);
}
}
))
.timeout(5, TimeUnit.SECONDS)
.subscribe(this::getScanResult, this::onConnectionFailure);
Its not working and looks like the retryWhen is not getting called. It may be more of rxJava issue but i will really appreciate any help on this.
As you wrote in the comments your this::onUnsubscribe is calling subscription.unsubscribe() so the .retryWhen() operator has no possibility of being called.
You could move the .doOnUnsubscribe() below of .retryWhen() or the other way around to give get the intended behaviour.

Web API: Chrome Network tab reports huge request processing time, but the request finishes in milliseconds

I'm working on some performance issues on an ASP.NET / Angular website, and I noticed something quite interesting in Google Chrome that I can't understand.
The time it takes the .NET Web Api to finish the request takes a few milliseconds, but Google Chrome reports it taking a few seconds.
Here are some screenshots to illustrate what I mean:
As you can see the request took 2,59 seconds to complete.
If I take out this request and do it solo (right clicking and selecting 'Open in new Tab', I get a completely different result, like seen here:
This time, the request took 81 ms, which is a huge difference from the 2,59 seconds reported in the first screenshot.
Debugging the app has shown me that there's nothing special going on in this request. It simply returns a list. The query that does this is FAST. I can also run this request 100x and it remains fast, yet in the app it seems to be slow.
I'm at a loss at what could be going on.
I have investigated the following:
I thought my web api was handling the requests coming in one by one, first finishing the first request and then moving on to the second one. I have tested this by putting breakpoints on both web api methods and they are fired at the same time and complete intermittently.
I thought it may be due to the first request in Entity Framework being slow and afterwards being fast. It's not, because if I load the page a first time, and then a second time, I see the exact same results.
The request is done with Angular, like so:
return $http.get(service.url + '/organisationsorts').success(function(data)
{ //data is processed here });
Does anyone have any suggestions on how to further look at this? What things I can try?
The technologies used are:
.NET Web Api
Entity Framework
Angular JS to do the request
An example of the Web Api Request:
[Route("organisationsorts")]
[HttpGet]
public IList<SortOrganizationListDto> GetAllOrganisationSorts()
{
return _service.GetAllOrganisationSorts();
}
And the corresponding implementation:
public IList<SortOrganizationListDto> GetAllOrganisationSorts()
{
try
{
return Uow.GetStandardRepo<SortOrganisation>().GetAll().OrderBy(x => x.Name).Project().To<SortOrganizationListDto>().ToList();
}
catch (Exception ex)
{
LogError("GetAllOrganisationSorts has failed", ex);
return null;
}
}
This selects 5 rows from the table using Entity Framework and projecting it via AutoMapper to a ListDto.

Can a thread in ASP.NET work keep continue after Response.End?

I want to make a tcp connection to a device and keep continously retrieve data from device. I want to start this with a simple request and keep it working background even Page response completed. Is this possible in asp.net?
Can a thread in ASP.NET work keep continue after Response.End?
Yes, you can if you do not care or do not need the result.
For example, in the following code, you call AddLogAsync and insert a log, but you not care whether insert successful or not.
public Task AddLogAsync(Log log)
{
return Task.Run(() => AddLog(log));
}
private void AddLog(TraceLog traceLog)
{
// Do something here.
}
I want to make a tcp connection to a device and keep continously
retrieve data from device. I want to start this with a simple request
and keep it working. Is this possible in asp.net?
I'm not really understanding above question. After Response.End, you cannot return anything, although you can continue work on something in different thread.

How to debug slow meteor methods?

A number of my meteor methods have mysteriously slowed down recently. Whereas they used to be quite snappy, many are taking 10 or so seconds.
Things not causing the slowdown:
Additional functionality, the slowed sections of the codebase haven't been changed significantly
Machine load (cpu load hovering around 30%)
Additional DB load (no new queries added)
transfer time of the return data (returns undefined)
blocking method (I've tried with this.unblock() within the method)
I did debugging by using console.time() / console.timeEnd() on both the server and client side. The server side code takes about .3 seconds to run, but the client doesnt get the callback until about 11 seconds after the meteor.call() ...
This is the server method:
function cancelSomething(somethingId, reason) {
console.time('cancelSomething method');
check(somethingId, String);
check(reason, String);
if (!AuthChecks()))
throw new Meteor.Error(401, 'Not Authorized');
var something = MySomethings.findOne({'_id': somethingId});
if (!something)
throw new Meteor.Error(404, 'Something not found');
var returnVal = SomethingService.cancel(something, reason);
console.timeEnd('cancelSomething method'); // <--- prints "cancelSomething 350ms" or there abouts
return returnVal;
}
clientSide:
console.time('meteorCall');
Meteor.call('cancelSomething', this._id, reason, function(err) {
if (err) {
console.log('an error occurred', err);
}
console.timeEnd('meteorCall'); // <--- prints "meteorCall 11500" or so
});
EDIT:
I have noticed there is some correlation with the quantity of docs within the "somethings" in the db. w/ 500 documents it takes about 1 second to receive the return on the client, with 5000 it takes about 8.5 seconds ...
Interesting. I think this one is hard to answer without knowing more about your app, but I have some suggestions that could help steer you in the right direction.
blocking
If we can assume that the timers are working properly, what could be happening is that the server is unable to begin execution of the method because another method call by the same client is already in progress. Have a look at unblock in the docs. The answer may be as simple as putting a this.unblock at the top of one of your methods.
syncing
If SomethingService.cancel does something which results in a lot of DDP traffic, that could tie up the client for a while and make it unable to execute your callback. For example if it:
modified or created a lot of documents which then had to be synced to the client
indirectly caused an expensive subscription to be rerun (my money is on this one)
Updated Answer
It seems the problem had to to with a call to observe, which makes a lot of sense given your high CPU load. Frankly, it's a little silly that I didn't suggest this because I have already answered a similar question here. If you want to try to keep the observe, here are some additional suggestions:
Use oplog tailing.
Try to narrow the scope of the observe as much as possible using selectors which are currently supported by the oplog observe driver. The supported selectors should improve at or before meteor 1.0.
Limit the fields to only those you need.
Check that oplog tailing is working by adding the facts package.

Resources