In Grails service, I would like to render a page while another method is running asynchronously. I tried different things from the documentation async and gpars library. None of the listed things worked as desired.
GParsPool.withPool(2) {
this.&longFunction.callAsync(command)
rendering()
}
later tried
GParsPool.withPool(2) {
def a ={longFunction(command)}.async()
a()
rendering()
}
Related
The notification always appears "Migrations: Finished migrating." before the real migration seed is finished. I chained all. I've checked all.
During migration, we use the async mechanism.
const { db } = MongoInternals.defaultRemoteCollectionDriver().mongo;
I've just found that MeteorMigration does not support promise-based functional. As a solution we use Meteor.wrapAsync. But it does not help.
const wrapIntoMongoTransaction = Meteor.wrapAsync(function (func, callback) {
wrapIntoMongoTransactionAsync(func).then(callback);
});
And then simply call.
Promise.await from the package meteor/promise does it well. It makes asynchronous to synchronous code.
My code becomes looking the following way:
import { Promise } from 'meteor/promise';
function wrapIntoMongoTransaction(func) {
Promise.await(wrapIntoMongoTransactionAsync(func));
}
Is it possible to stub meteor methods and publications in cypress tests?
In the docs (https://docs.cypress.io/guides/getting-started/testing-your-app#Stubbing-the-server) it says:
This means that instead of resetting the database, or seeding it with
the state we want, you can force the server to respond with whatever
you want it to. (...) and even test all of the edge cases, without needing a server.
But I do not find more details about that. All I can find is, that when not using the virtual user in the tests to fill the database, it is possible to call API calls on the app, like so:
cy.request('POST', '/test/seed/user', { username: 'jane.lane' })
.its('body')
.as('currentUser')
In my opinion that is not a "stub". It is a method to "seed" the database.
Is it possible to tell cypress to answer a meteor method in the client code like
Meteor.call('getUser', { username: 'jane.lane' }, callbackFunction);
with some data, it would give back in production?
I can only show an example using sinon to stub Meteor method calls:
const stub = sinon.stub(Meteor, 'call')
stub.callsFake(function (name, obj, callback) {
if (name === 'getUser' && obj.username === 'jane.lane') {
setTimeout(function () {
callback(/* your fake data here */)
})
}
})
That would be of corse a client-side stub. You could also simply override your Meteor method for this one test.
I have this formatter in my .NET Core 3.1 project (which I recently upgraded from 2.1):
public class JilOutputFormatter : TextOutputFormatter {
public JilOutputFormatter() =>
JilFormatterConfig.AddSupportedHeaders(SupportedMediaTypes, SupportedEncodings);
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) {
using (var writer = new StreamWriter(context.HttpContext.Response.Body)) {
JSON.Serialize(context.Object, writer, MyOptions);
writer.Flush();
}
return Task.FromResult(true);
}
}
And I'm adding it to pipeline with this snippet:
services.AddMvcCore(o => {
o.OutputFormatters.Insert(0, new JilOutputFormatter());
}).AddOthersBlahBlah();
It was working like a charm when the application was on 2.1. But now on 3.1 I'm getting this error:
An unhandled exception occurred while processing the request.
InvalidOperationException: Synchronous operations are disallowed. Call
WriteAsync or set AllowSynchronousIO to true instead.
I tried to async the write operation, but can't find the method on Jil. Do you have any idea please?
NOTE: I know there are some answers - like this one - that are saying how to AllowSynchronousIO. But I'm interested on how to async write in Jil.
You'll have to use the 3.0 alpha versions. Jil doesn't even include the word Task in the source code in the latest stable version, 2.17 (or Github search is having some issues).
Version 3.0 uses Pipelines directly. You can use the SerializeAsync(T, PipeWriter , Encoding, Options, CancellationToken). Maybe you can work with HttpContext.Response.BodyWriter. I haven't tested this though.
Eg :
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context,
Encoding selectedEncoding)
{
var data=context.Object;
var writer=contest.Response.BodyWriter;
await JSON.SerializeAsync(data,writer,selectedEncoding);
}
Errors can revolve around ReadAsync, WriteAsync, and FlushAsync with outputs similar to what is listed below.
Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
Synchronous operations are disallowed. Call WriteAsync or set AllowSynchronousIO to true instead.
Synchronous operations are disallowed. Call FlushAsync or set AllowSynchronousIO to true instead.
As a temporary workaround, you can set the value of AllowSynchronousIO in your ConfigureServices method found in your Startup class.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
// If using IIS:
services.Configure<IISServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
// other services
}
It isn’t a great workaround, but it will keep you moving forward. The better solution is to upgrade your libraries and perform all your actions asynchronously.
See the detailed post .NET Core 3.0 AllowSynchronousIO Workaround by Khalid Abuhakmeh
TLDR: As of Dotnet Core 5.0, the default web-server (Kestral) is designed to perform only Async Level work to be the most performant. Enable Sync within Kestral.
Rational: Due to to the majority of software being more IO Dependent than CPU Dependent, Async Programming allows for the system to perform other work, while waiting for the IO to complete (IE; Writing to Disk, Reading something from the network).
Place this within Startup.cs within the ConfigurationService function.
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
I'm playing around with HttpServer; and was adding support for serving static files (I'm aware of Shelf; I'm doing this as a learning exercise). I have a list of handlers that are given the opportunity to handle the request in sequence (stopping at the first that handles it):
const handlers = const [
handleStaticRequest
];
handleRequest(HttpRequest request) {
// Run through all handlers; and if none handle the request, 404
if (!handlers.any((h) => h(request))) {
request.response.statusCode = HttpStatus.NOT_FOUND;
request.response.headers.contentType = new ContentType("text", "html");
request.response.write('<h1>404 File Not Found</h1>');
request.response.close();
}
}
However, as I implemented the static file handler, I realised that I couldn't return true/false directly (which is required by the handleRequest code above, to signal if the request is handled) unless I use file.existsSync().
In something like ASP.NET, I wouldn't think twice about a blocking call in a request because it's threaded; however in Dart, it seems like it would be a bottleneck if every request is blocking every other request for the duration of IO hits like this.
So, I decided to have a look in Shelf, to see how that handled this; but disappointingly, that appears to do the same (in fact, it does several synchronous filesystem hits).
Am I overestimating the impact of this; or is this a bad idea for a Dart web service? I'm not writing Facebook; but I'd still like to learn to write things in the most efficient way.
If this is considered bad; is there a built-in way of doing "execute these futures sequentially until the first one returns a match for this condition"? I can see Future.forEach but that doesn't have the ability to bail. I guess "Future.any" is probably what it'd be called if it existed (but that doesn't)?
Using Shelf is the right approach here.
But there is still a trade-off between sync and async within the static handler package.
Blocking on I/O obviously limits concurrency, but there is a non-zero cost to injecting Future into a code path.
I will dig in a bit to get a better answer here.
After doing some investigation, it does not seem that adding async I/O in the shelf_static improves performance except for the bit that's already async: reading file contents.
return new Response.ok(file.openRead(), headers: headers);
The actual reading of file contents is done by passing a Stream to the response. This ensures that the bulk of the slow I/O happens in a non-blocking way. This is key.
In the mean time, you may want to look at Future.forEach for an easy way to invoke an arbitrary number of async methods.
There are a lot of good questions in your post (perhaps we should split them out into individual SO questions?).
To answer the post title's question, the best practice for servers is to use the async methods.
For command-line utilities and simple scripts, the sync methods are perfectly fine.
I think it becomes a problem if you do file access that is blocking for a long time (reading/writing/searching big files locally or over the network).
I can't imagine file.existsSync() doing much damage. If you are already in async code it's easy to stay async but if you have to go async just for the sake of not using file.existsSync() I would consider this premature optimization.
A little offtopick, but it solved my problem, I was trying to solve by reading discussion on this question. I was not able to achieve async operation in handler with io.serve, so I used dart:io for active pages and shelf.handleReguest for static files:
import 'dart:io';
import 'dart:async' show runZoned;
import 'package:path/path.dart' show join, dirname;
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_static/shelf_static.dart';
import 'dart:async';
import 'package:sqljocky/sqljocky.dart';
void main(){
HttpServer
.bind(InternetAddress.ANY_IP_V4, 9999)
.then((server) {
server.listen((HttpRequest request) {
String path = request.requestedUri.path;
if(path == "/db"){
var pool = new ConnectionPool(host: 'localhost', port: 3306, user: 'root', db: 'db', max: 5);
var result = pool.query("select * from myTable");
result.then((Results data) {
data.first.then((Row row) {
request.response.write(row.toString());
request.response.close();
});
});
}else{
String pathToBuild = join(dirname(Platform.script.toFilePath()), '..', 'build/web');
var handler = createStaticHandler(pathToBuild, defaultDocument: 'index.html');
io.handleRequest(request, handler);
}
});
});
}
Many months later I've found how to create that Stream... (still offtopick .. a little)
shelf.Response _echoRequest(shelf.Request request) {
StreamController controller = new StreamController();
Stream<List<int>> out = controller.stream;
new Future.delayed(const Duration(seconds:1)).then((_){
controller.add(const Utf8Codec().encode("hello"));
controller.close();
});
return new shelf.Response.ok(out);
}
I'm just getting into QUnit testing, and have run into a problem on my first page :S
We use ASP.NET Service References to take advantage of async data loading on html pages, creating a reference to a web service in the same project. What ASP.NET does behind the scenes (ScriptManager control) is create a JS file representing the service methods and handling all the AJAX calling.
Using this, I have a page that calls one of these methods in the document.ready jQuery event. I'm now trying to test against this js file using QUnit, but avoid having the js file call the actual web service and use a mock service instead. Here's what I have for an attempt so far:
main.js (production code file)
var Service;
$(document).ready(function () {
//class definition created by asp.net behind the scenes
Service = MyProject.services.DataService;
//the method that calls the service
LoadData();
});
function LoadData() {
Service.GetData(OnGetDataSuccess, OnGetDataFailure);
}
main-test.js (test QUnit code, main.js is referenced in this page)
function SetupMockService(result) {
Service = { "GetData": function (OnSuccess, OnFailure) {
GetDataCalled = true;
OnSuccess(result);
//this is required in an asyncTest callback, I think?
start();
}, "GetDataCalled": false};
}
$(document).ready(function () {
module("LoadData");
asyncTest("LoadData should call GetData from service", function () {
SetupMockService(result);
LoadData();
equals(Service.GetDataCalled, true, "GetData has been called");
});
This test fails. The LoadData method is called as part of the original (main.js) document.ready event, so it still calls the production web service, and the tests fail because that GetDataCalled variable is never set (or defined in production). Am I doing the asyncTest wrong? (This is my first day with QUnit, so I could very well be)
The other way I can see this working is if I can override the main.js document.ready event, but I'm not quite sure on how to do that. I also don't want to add "testEnvironment == true" checks to my production main.js code.
Turns out I had things a bit backwards, as well as one obvious mistake. Here's the resulting code that works
main-tests.js
//the test itself isn't calling async methods, so it doesn't need to use asyncTest
test("LoadData should call GetData from service", function () {
SetupMockService();
LoadData();
equals(Service.GetDataCalled, true, "GetData has been called");
});
function SetupMockService() {
//redefining the Service variable specified in main.js with a mock object
Service = { "GetData": function (OnSuccess, OnFailure) {
//I forgot the "this" part... d'oh!
this.GetDataCalled = true;
}, "GetDataCalled": false
};
}
This still doesn't fix the issue with the original main.js's document.ready code being executed, but I'll figure that out.