How to set Execution Timeout in Hotchocolate 10.4.3 - graphql

we are using Hotchocolate 10.4.3 for my .net core service.
we are using code first approach.
All settings are in startup.cs exactly similar to their Star War example.
Hotchocolate web site says default timeout for request is 30 sec but I found my application throwing Transaction error after 1 min.
I want to increase that to 2 min.
Also why server still executes everything even after timeout exception.
I always see Transaction error at end after all my code gets execute properly.
If everything is going to run properly why to even then throw error?
I'm still learning graphql. Please correct me if anything sounds incorrect.

In HotChocolate v10, you can set the execution timeout when you add the service in your Startup's ConfigureServices() method:
services.AddGraphQL(
SchemaBuilder.New()
.AddQueryType<Query>()
.Create(),
new QueryExecutionOptions { ExecutionTimeout = TimeSpan.FromMinutes(2) });
They have a good repo of examples here: https://github.com/ChilliCream/hotchocolate-examples
Documentation on the execution options: https://chillicream.com/docs/hotchocolate/v10/execution-engine/execution-options
EDIT: In v11, the syntax has changed:
services
.AddGraphQLServer()
.AddQueryType<Query>()
.SetRequestOptions(_ => new HotChocolate.Execution.Options.RequestExecutorOptions { ExecutionTimeout = TimeSpan.FromMinutes(10) });

Related

Elsa workflow versioning

I have created a simple workflow, first time publish it is working fine when I change something and publish then it is throwing an exception: "The call is ambiguous and matches multiple workflows". How to handle this?
I was experiencing the same issue. There appears to be an issue in Elsa where the "IsLatest" flag on the WorkflowDefinition table doesn't get turned off for the prior version of that workflow. There is some documentation around the issue here:
https://gitmemory.com/issue/elsa-workflows/elsa-core/1293/886656398
In my case, I fixed this by manually setting the prior version's IsLatest to 0 and restarting Elsa. The restart was important, as there appears to be some caching related to the workflow newness.
TL;DR : there are multiple workflows with the same path
Check if you are building a workflow through ELSA DESIGNER and at the same time there is a workflow that is triggered when HTTP requests are made to the same URL
public class HelloWorld : IWorkflow
{
public void Build(IWorkflowBuilder builder)
{
builder
.HttpEndpoint("/hello") // this is the endpoint that is causing conflict
.When(OutcomeNames.Done)
.WriteHttpResponse(HttpStatusCode.OK, "<h1>Hello World!</h1>", "text/html");
}
}

Debugging topshelf as a service

I am having problems running TopShelf as a service and I am not getting much info to help troubleshoot. I am using dotNet core 2.2.
I get this error when I start it:
Error: 1053: The service did not respond to the start or control
request in a timely fashion.
Event logs show:
A timeout was reached (30000 milliseconds) while waiting for the Test service to connect.
The Test service failed to start due to the following error: The service did not respond to the start or control request in
a timely fashion.
It message shows a 30 second timeout in the error popup happens in about 1 second. I don't think its a time out.
I my current setup I am using an IHostedService, but I have tried it without this. Here is the current setup.
var hostBuilder = SetupHost();
var rc = HostFactory.Run(x =>
{
x.Service<IHost>(s =>
{
s.ConstructUsing(name => hostBuilder.Build());
s.WhenStarted(tc =>
{
_logger = tc.Services.GetRequiredService<ILogger<Kickoff>>();
tc.StartAsync();
});
s.WhenStopped(tc => tc.StopAsync());
});
x.RunAsLocalService();
x.SetDescription("Test");
x.SetDisplayName("Test");
x.SetServiceName("Test");
x.EnableShutdown();
x.OnException(p => ExceptionOccured(p));
});
If you see something glaring people let me know.
My main goal is to find a technique to troubleshoot this. I've tried logging to a file with system.io but it does not produce results. I don't know how to debug it or get meaning information.

Couchbase Lite iOS Replication stops replicating after restart

I'm still a bit new to Couchbase and iOS, but I'm running into a problem restarting my replications that I'm having trouble with. Here are a few notes about the flow.
The backend is using custom authentication.
When the user logs in, a new session is created in the sync gateway and those session details are returned to the iOS device. The app then uses those credentials to set up a push and pull replication (I've dropped the push replication for now while trying to debug this). The options on the replications aren't much and are as follows:
let pull = self.database.createPullReplication(self.remoteDBURL);
pull.continuous = true;
pull.headers["uuid"] = "device-1";
pull.setCookieNamed(sessionName, withValue: sessionId, path: "/", expirationDate: cookieExpirationDate, secure: false);
pull.start();
self._pull = pull;
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(DataService.replicationChanged(_:)), name: kCBLReplicationChangeNotification, object: self._pull);
This works great and all the proper documents are synced to the device. Currently I have the backend created cookies that only last for about 5 minutes so I can test the refreshing of cookies. So, during the first few minutes, any docs I add to the channel that the app gets, the app receives the doc and all is good.
About halfway into the life of the token, the backend is set up to return with a 401 error telling the app to use it's token to get a new token. So, I have this in the replication change listener:
#objc public func replicationChanged(n: NSNotification) {
let replication = n.object as! CBLReplication;
let error = replication.lastError;
if (error != nil) {
print("last error is NOT nil");
print("last error = \(error)");
switch error!.code {
case 401:
self.updateReplicationSession();
default:
break;
}
}
}
Then, the updateReplication function looks like this:
... make http call to getNewToken url using the 'old' or 'soon to be expired' token. *The server is successfully returning this new session.
self._pull.setCookieNamed(newSessionName, withValue: newSessionId, path: "/", expirationDate: newExpirationDate, secure: false);
self._pull.restart();
...
It is at this time that the syncing stops working. No errors are thrown that I can see of other than once I received a CFNetwork Internal error. I can see on the server logs that the replication sends in the new session once... then everything just seems to hang for the replication. Any new docs to a channel that it gets and it doesn't get them. I don't see anything in the Sync Gateway logs indicating what the problem is. However, I'm still pretty new to this... so there may be something. Additionally, I set up a function to run every few seconds and print the status of the replication and it is stuck on ACTIVE.
I'm using sync gateway v 1.3 and CBL ios 1.3. I was using version 1.2.1 and was having this problem... hoping ugrading to 1.3 would magically fix it. It didn't, but I'm not sure I should go back to 1.2.1.
I'm completely stumped on this. I've searched high and low and often seem to find an answer that fits the bill... but it still doesn't work.
I've tried delaying the updating of the session in order for all calls from replication to 'fail' first. I've tried just calling start() on the replication thinking that maybe the 401 killed the replication and restart() isn't going to do anything. I've called stop()... then waited a bit and called start(). Not sure what to do next.
Any help is appreciated guys! Is it possible the local DB on the phone and the sync gateway have a unresolvable rev problem?
EDIT 1
The only way I can currently get it to work is to completely delete the local db in the replication changed function and restart it... then start a new replication... this works... unfortunately though, I then have to broadcast a notification so that any table view that may be up reloads the query. This causes a refresh animation in tableviews and isn't sustainable... but at least I can keep moving for now.
EDIT 2
I found how to enable better logging of the CBL on iOS and here's an error I keep seeing after a token refresh/ replication restart:
CBLWebSocketChangeTracker[0x7ff9bb53b5e0 iphone]: Connection error #8, retrying in 256.0 sec: PSWebSocketError[3, "Output stream end encountered"]
Thoughts?
EDIT 3
I changed things around a bit to get rid of the refreshing of tokens. I attempted to make it so when a user logs in from the iOS app, the backend creates a session with the sync gateway for that user and returns it. The app then starts a replication with that session. Then, after the 5 minutes (the ttl used when creating the session), the next time the app tries to sync, it will get a 401 and stop the replication and present the login screen. Then, when the user logs in again, a new session is created, etc...
I found 2 things:
-Anytime I added a doc to a channel that would sync with the app, when the app synced, the session expiration date would increase by about 20ish seconds. Is this normal behavior? The only way it would log the user out on the expired token is if I didn't add any docs for long enough.
-The restarted replication still gets stuck. Here are the logs for the sync gateway and xcode:
This is the last part of the sync gateway when the session is expired... which will send the 404 to the app.
2016-08-23T21:11:51.089-05:00 Changes+: Sending seq:163 from channel jmoore2
2016-08-23T21:11:51.089-05:00 Changes+: MultiChangesFeed sending &{Seq:163 ID:un:jmoore2_116 Deleted:false Removed:{} Doc:map[] Changes:[map[rev:1-e775ef6713dc39f6d52d35cefb396fe3]] Err:<nil> allRemoved:false branched:false} (to jmoore2)
2016-08-23T21:11:51.089-05:00 Changes: MultiChangesFeed done (to jmoore2)
2016-08-23T21:11:51.089-05:00 HTTP+: #212: --> 200 OK (0.0 ms)
2016-08-23T21:11:51.459-05:00 HTTP: #216: GET /my_gateway/_session/3fa29222db286e8ec67a51e88b613ba4cd5cbf31 (ADMIN)
2016-08-23T21:11:51.459-05:00 HTTP: #216: --> 404 missing (0.2 ms)
2016-08-23T21:11:51.461-05:00 HTTP: #217: GET /my_gateway/_session/3fa29222db286e8ec67a51e88b613ba4cd5cbf31 (ADMIN)
2016-08-23T21:11:51.461-05:00 HTTP: #217: --> 404 missing (0.2 ms)
Then, when the user logs back in, here are SG log for that:
2016-08-23T21:15:41.200-05:00 HTTP: #223: GET /my_gateway/_session/1a6105eaf2c91de320a47422041c655dd3d5c279 (ADMIN)
2016-08-23T21:15:41.201-05:00 HTTP+: #223: --> 200 (0.5 ms)
2016-08-23T21:15:41.203-05:00 HTTP: #224: GET /my_gateway/_local/78c229762074a95c864f7fecc03ce88f0ef6c499 (as jmoore2)
2016-08-23T21:15:41.203-05:00 HTTP+: #224: --> 200 (0.5 ms)
2016-08-23T21:15:41.371-05:00 Cache: Received #164 after 455ms ("user-login-info:jmoore2" / "48-ea0b2d9771fa2be1d76838f9e4d55081")
2016-08-23T21:15:41.371-05:00 Cache: #164 ==> channel "*"
2016-08-23T21:15:41.371-05:00 Changes+: Notifying that “mdatabase” changed (keys="{*}") count=31
And the xcode log when restarting the replication immediately goes to this:
21:15:41.195‖ Sync: CBLRestPuller[http://mycomp.local:8080/iphone/]: Reachability state = <mycomp.local>:reachable (30002), suspended=0
21:15:41.205‖ Sync: CBLRestPuller[http://mycomp.local:8080/iphone/]: Server is Couchbase Sync Gateway/1.3.0
21:15:41.205‖ Sync: CBLRestPuller[http://mycomp.local:8080/iphone/]: Replicating from lastSequence=162
21:15:41.205‖ Sync: CBLRestPuller[http://mycomp.local:8080/iphone/] starting ChangeTracker: mode=3, since=162
21:15:41.207‖ ChangeTracker: CBLWebSocketChangeTracker[0x7f97d8698190 iphone]: Starting...
21:15:41.207‖ Sync: CBLWebSocketChangeTracker[0x7f97d8698190 iphone]: GET //mycomp.local:8080/iphone/_changes?feed=websocket
21:15:41.208‖ ChangeTracker: CBLWebSocketChangeTracker[0x7f97d8698190 iphone]: Started... <http://mycomp.local:8080/iphone/_changes?feed=websocket>
21:15:41.211‖ CBLWebSocketChangeTracker[0x7f97d8698190 iphone]: Connection error #1, retrying in 2.0 sec: PSWebSocketError[3, "Output stream end encountered"]
and also sometimes this error shows up:
2016-08-23 21:01:15.232 MyApp[52094:36001215] 52094: CFNetwork internal error (0xc01a:/BuildRoot/Library/Caches/com.apple.xbs/Sources/CFNetwork_Sim/CFNetwork-758.3.15/Loading/URLConnectionLoader.cpp:289)

Async Spring Controllers vs normal Controllers

I wanted to analyze the improvement I may see by enabling Async Controllers in Spring Boot over normal controller
So here is my test code. One API returns a Callable and another is normal controller API. Both APIs block for 10secs simulating a long running task
#RequestMapping(value="/api/1",method=RequestMethod.GET)
public List<String> questions() throws InterruptedException{
Thread.sleep(10000);
return Arrays.asList("Question1","Question2");
}
#RequestMapping(value="/api/2",method=RequestMethod.GET)
public Callable<List<String>> questionsAsync(){
return () -> {
Thread.sleep(10000);
return Arrays.asList("Question2","Question2");
};
}
I set up embedded tomcat with this configuration i.e only one tomcat processing thread:
server.tomcat.max-threads=1
logging.level.org.springframework=debug
Expectations for /api/1
Since there is only one tomcat thread, another request will not be entertained untill this is processed after 10secs
Results:
Meet expectations
Expectations for /api/2
Since we are returning a callable immediately, the single tomcat thread should get free to process another request. Callable would internally start a new thread. So if you hit the same api it should also gets accepted.
Results:
This is not happening and untill the callable executes completely, no further request is entertained.
Question
Why is /api/2 not behaving as expected?
#DaveSyer is right, /api/2 is actually behaving as expected.
I assume you are testing the behavior with a web browser. At least Firefox and Chrome are preventing multiple simultaneous requests to the same URL. If you open 2 tabs with api/2, the second one will only send a request to the application after the first got the response.
Try testing it with a simple bash script, like:
curl localhost/api/2 &
curl localhost/api/2 &
curl localhost/api/2 &
It will print 3 responses around the same time.
Just want to mention that server.tomcat.max-threads is deprecated since Spring boot 2.3. Now use server.tomcat.threads.max in your Spring application.properties. The default is 200.

Actionscript 4: NetConnection.connect(...) does not fire a NetStatusEvent event

I downloaded the red5-recorder (http://www.red5-recorder.com/) , which fails to allow me to start recording. After debugging I found that the netconnection, needed to record to a media server, created does not fire a NetStatusEvent event, so essentially it fails silently. I have implemented the connection with the following minimal working example:
trace("make net connection");
nc = new NetConnection();
nc.client = { onBWDone: function():void{ trace("bandwidth check done.") } };
trace("add event listener");
nc.addEventListener(NetStatusEvent.NET_STATUS, function(event:NetStatusEvent) {
trace("handle");
});
trace("connect!");
nc.connect("rtmp://localshost/oflaDemo/test/");
trace("connect done");
The output of this piece of code is:
make net connection
add event listener
connect!
connect done
The actionscript api states that the connect-call always fires such an event:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetConnection.html#includeExamplesSummary
Moreover, the netconnection is not 'connected' (a state of the NetConnection object) 10 seconds after the call. I also took a look at this: NetConnect fails silently in Flash when called from SilverLight But the fix suggested by the author, swapping rtmp and http in the connection uri, do not work. Also, I tested the uri and in fact the exact same code sniplet in a personal project, where it did work. I just can not seem to find why connecting to a media server fails silently in the red5-recorder project.
The awkward part is that if I pass some random string as a conenction uri, still nothing happens (no event, no exception, no crash). Also not setting nc.client becore nc.connect(), which caused exceptions in my experience, did not cause exceptions.
Any suggestions are welcome.
You are setting the address to localshost instead localhost.
nc.connect("rtmp://localshost/oflaDemo/test/");
Correct address:
nc.connect("rtmp://localhost/oflaDemo/test/");

Resources