How to avoid freezing the UI on heavy computation - flutter

Trying to decrypt JSON from server with Interceptor (from dio). But UI freezes during decryption.
class DecryptInterceptor extends Interceptor {
#override
Future onResponse(Response response) async {
response.data = decrypt(response.data); //freezes here
return super.onResponse(response);
}
}
Object decrypt(Object object){
// computations
}

Asynchronous programming paradigm is based on single threaded model. Async optimizes CPU usage by not waiting I/O tasks to complete. Instead, it puts a callback to the task and tells it "call this when you done". Now it can handle other work while the task completes and calls the callback. This makes sense when tasks are HTTP requests or file operations since these will handled by other devices not the CPU. But if the task is CPU intensive then using async will not help.
You can have a look at Isolate, equivalent of thread in Dart. You can create a seperate isolate and run your heavy tasks there.
There is also compute() method. It takes a function and argument, then evaluate that function with the supplied argument on a seperate isolate and returns the result as Future. This is much easier and gets the job done.
A dummy method that is CPU intensive:
int heavyTask(int n) {
int z = n;
for (var i = 0; i < n; i++) {
i % 2 == 0 ? z-- : z += 3;
}
return z + n;
}
Using compute() method to run it on a seperate isolate:
compute(heavyTask, 455553000)
.then((res) => print("result is $res"));

You can use compute property that flutter provides to perform tasks in another isolate. It exists exactly for such tasks.
class DecryptInterceptor extends Interceptor {
#override
Future onResponse(Response response) async {
response.data =await compute(decrypt,response.data); //freezes here
return super.onResponse(response);
}
}
Object decrypt(Object object){
return result;
}
It has some restrictions though for the type of data you can pass in argument and retrieve as result. You can learn more here.

Related

How to return the processing result of a signal?

Especially if the signal processing needs to invoke an/some activities, how can I achieve that?
I tried to return data or exception but it doesn't work.
Data cannot be returned from signal method. Throwing exception will block workflow execution.
Common mistakes
It's wrong to return data in a signal method, or throw an exception -- because signal method is meant to be Asynchronous. The processing must be like Kafka processing messages and you can't return the result via the method returning.
So below code will NOT work:
public class SampleWorkflow{
public Result mySignalMethod(SignalRequest req){
Result result = activityStub.execute(req)
if(...){
throw new RuntimeException(...)
}
return result
}
}
What should you do
What you must do:
Make sure signal don't return anything
Use a query method to return the results
In signal method processing, store the results into workflow state so that query can return the states
A bonus if you also use the design pattern to store signal request into a queue, and let workflow method to process the signal. This will give you some benefits
Guarantee FIFO ordering of signal processing
Make sure reset workflow won't run into issues -- after reset, signals will be preserved and moved to earlier position of the workflow history. Sometimes workflow are not initialized to replay the signals.
Also make exception handling easier
See this design pattern in sample code: Cadence Java sample/Temporal java sample
If we applied all above, the sample code should be like below :
public class SampleWorkflow{
private Queue<SignalRequest> queue = new Queue<>();
private Response<Result> lastSignalResponse;
public void myWorkflowMethod(){
Async.procedure(
() -> {
while (true) {
Workflow.await(() -> !queue.isEmpty());
final SignalRequest req =
queue.poll();
// alternatively, you can use async to start an activity:
try{
Result result = activityStub.execute(req);
}catch (ActivityException e){
lastSignalResponse = new Response( e );
}
if(...){
lastSignalResponse = new Response( new RuntimeException(...) );
}else{
lastSignalResponse = new Response( result);
}
}
});
...
}
public Response myQueryMethod(){
return lastSignalResponse;
}
public Result mySignalMethod(SignalRequest req){
queue.add(req)
}
}
And in the application code, you should signal and then query the workflow to get the result:
workflowStub.mySignalMethod(req)
Response response = workflowStub.myQueryMethod()
Follow this sample-Cadence / sample-Temporal if you want to use aysnc activity
Why
Signal is executed via Workflow decision task(Workflow task in Temporal). A decision task cannot return result. In current design, there is no mechanism to let a decision task return result to application code.
Throw exception in workflow code will either block the decision task or fail the workflow).
Query method is designed to return result. -- However, query cannot schedule activity or modify workflow states.
It's a missing part to let app code to make a synchronous API call to update and return data. It needs a complicated design: https://github.com/temporalio/proposals/pull/53

async/await - calling an async API from a syncronous method using dart [duplicate]

I'm on the way to evaluate Dart for a German company by porting various Java programs to Dart and compare and analyze the results. In the browser Dart wins hands down. For server software performance seemed to be a serious isssue (see this question of me) but that got mostly defused.
Now I'm in the area of porting some "simple" command-line tools where I did not expect any serious problems at all but there is at least one. Some of the tools do make HTTP requests to collect some data and the stand-alone Dart virtual machine only supports them in an asynchronous fashion. Looking through all I could find it does not seem to be possible to use any asynchronous call in a mostly synchronous software.
I understand that I could restructure the available synchronous software into an asynchronous one. But this would transform a well-designed piece of software into something less readable and more difficult to debug and maintain. For some software pieces this just does not make sense.
My question: Is there an (overlooked by me) way to embed an asynchronous call into a synchronously called method?
I imagine that it would not be to difficult to provide a system call, usable only from within the main thread, which just transfers the execution to the whole list of queued asynchronous function calls (without having to end the main thread first) and as soon as the last one got executed returns and continues the main thread.
Something which might look like this:
var synchFunction() {
var result;
asyncFunction().then(() { result = ...; });
resync(); // the system call to move to and wait out all async execution
return result;
}
Having such a method would simplify the lib APIs as well. Most "sync" calls could be removed because the re-synchronisation call would do the job. It seems to be such a logical idea that I still think it somehow exists and I have missed it. Or is there a serious reason why that would not work?
After thinking about the received answer from lm (see below) for two days I still do not understand why the encapsulation of an asynchronous Dart call into a synchronous one should not be possible. It is done in the "normal" synchronous programing world all the time. Usually you can wait for a resynchronization by either getting a "Done" from the asynchronous routine or if something fails continue after a timeout.
With that in mind my first proposal could be enhanced like that:
var synchFunction() {
var result;
asyncFunction()
.then(() { result = ...; })
.whenComplete(() { continueResync() }); // the "Done" message
resync(timeout); // waiting with a timeout as maximum limit
// Either we arrive here with the [result] filled in or a with a [TimeoutException].
return result;
}
The resync() does the same that would normally happen after ending the main method of an isolate, it starts executing the queued asynchronous functions (or waits for events to make them executable). As soon as it encounters a continueResync() call a flag is set which stops this asynchronous execution and resync() returns to the main thread. If no continueResync() call is encountered during the given timeout period it too aborts the asynchronous execution and leaves resync() with a TimeoutException.
For some groups of software which benefit from straight synchronous programing (not the client software and not the server software) such a feature would solve lots of problems for the programer who has to deal with asynchrounous-only libraries.
I believe that I have also found a solution for the main argument in lm's argumentation below. Therefore my question still stands with respect to this "enhanced" solution which I proposed: Is there anything which really makes it impossible to implement that in Dart?
The only time that you can wrap an async method in a synchronous one is when you don't need to get a return value.
For example if you want to disable the save button, save results to the server asynchronously and re-enable the save button when the job is done you can write it like this:
Future<bool> save() async {
// save changes async here
return true;
}
void saveClicked() {
saveButton.enabled = false;
save()
.then((success) => window.alert(success ? 'Saved' : 'Failed'))
.catchError((e) => window.alert(e))
.whenComplete(() { saveButton.enabled = true; });
}
Note that the saveClicked method is fully synchronous, but executes the save method asynchronously.
Note that if you make saveClicked async, not only do you have to call it using the async pattern, but the entire method body will run asynchronously so the save button will not be disabled when the function returns.
For completeness the async version of saveClicked looks like this:
Future<Null> saveClicked() async {
saveButton.enabled = false;
try {
bool success = await save();
window.alert(success ? 'Saved' : 'Failed');
}
catch (e) {
window.alert(e);
}
finally {
saveButton.enabled = true;
}
}
Yes, this is way late, but I think this is a cool feature new people should know about.
There is a way, but the Dart docs warn against it (and it's somehow "experimental", although the implications aren't really discussed).
The waitFor command.
You basically pass in an asynchronous function that returns a Future, an optional timeout parameter, and the waitFor function will return the result.
For example:
final int number = waitFor<int>(someAsyncThatReturnsInt);
The resync function cannot be implemented in Dart's current execution model.
Asynchronous execution is contagious. A synchronous function must return before any other asynchronous events can execute, so there is no way to synchronously wait for asynchronous execution.
Execution in Dart is single-threaded and event based. There is no way for the resync function to block without it also blocking all other execution in the same isolate, so the pending async operations will never happen.
To block the synchronous execution, and continue executing something else, you need to preserve the entire call stack up to that point, and reinstate it later when the synchronous operations have completed. If you have that functionality, then there are probably better ways to do things than Future and Stream :)
Also, waiting for "all async execution" isn't well-defined in an event based system. There might be a broadcast Stream emitting events coming in from the network, a periodic timer, or a receive port getting data from another isolate, or some other source of events that you can't wait for because they come from outside the isolate, or event the process. When the current isolate shuts down, it might send a final shut-down message to another isolate, so effectively the "async execution" isn't over until the isolate dies.
Using the async/await syntax, you won't get synchronous operation, but it will be easier to code the similar asynchronous operation:
function() async {
var result = await asyncFunction();
return result;
}
It won't wait for async operations that aren't reflected in the Future returned by asyncFunction, but that's the job of asyncFunction to not complete until its operations are complete.
Dart is inherently async. Trying to avoid asynchronity won't work out.
There are sync versions of some API calls for example in dart:io and in some situations it might seem simpler to use them instead but because there aren't sync versions for all methods/functions you can't avoid async entirely.
With the recent introduction of the async/await feature programming async become much simpler and the code looks almost like sync code (but it isn't).
If a call went async it stays async. As far as I know there is nothing you can do about it.
import 'package:synchronized_lite/synchronized_lite.dart';
import 'dart:async';
// Using Lock as a mixin to further mimic Java-style synchronized blocks
class SomeActivity with Lock {
bool _started = false;
Future<bool> start() async {
// It's correct to return a Future returned by synchronized()
return synchronized(() async {
if(_started)
return false;
// perform the start operation
await Future.delayed(Duration(seconds: 1));
print("Started");
_started = true;
return true;
});
}
Future<void> stop() async {
// It's also correct to await a synchronized() call before returning
// It's incorrect to neither await a synchronized() call nor return its Future.
await synchronized(() async {
if(!_started)
return;
// perform the stop operation`enter code here`
await Future.delayed(Duration(seconds: 1));
print("Stopped");
_started = false;
});
}
}
// Prints:
// Started
// Stopped
main() async {
var a = SomeActivity();
print("Hello");
a.start();
a.start();
a.stop();
await a.stop();
}
/*Since the Await statement can be used in only asynchronous methods. Then we do two methods.I thinking first we call the async method and then we constantly query the null result for the non-async method. Then we get a synchronized model. In this way, we will wait for the answer in the non-async method. Such a method comes to my mind. But as far as I can see, there is no escape from the async working model in flutter dart language. Need to get used to it.It may be unprofessional, but I wanted to share the solution that came to my mind. hope it helps.
Stock resultStockQueryByBarcodeAsync;
bool waitStockQueryByBarcodeAsyncCompleted = false;
Stock WaitStockQueryByBarcodeAsync(String barcode, int timeOut) {
CallStockQueryByBarcodeAsync(barcode);
var startTime = new DateTime.now();
while (!waitStockQueryByBarcodeAsyncCompleted) {
Duration difference = DateTime.now().difference(startTime);
if (difference.inMilliseconds > timeOut) {
throw TimeoutException("Timeout Exceeded");
}
//we must scope time. Because it can be enter endless loop.
}
return resultStockQueryByBarcodeAsync;
}
void CallStockQueryByBarcodeAsync(String barcode) async {
waitStockQueryByBarcodeAsyncCompleted = false;
resultStockQueryByBarcodeAsync = null;
var stock = await StockQueryByBarcodeAsync(barcode);/*your target async method*/
waitStockQueryByBarcodeAsyncCompleted = true;
resultStockQueryByBarcodeAsync = stock;
}
In my case, I had to initialize the database connection from constructor. I am pretty new in Flutter and I don't know what are the best practices right now. But, here is what I did.
class Storage {
late Database database;
Storage() {
getConnection().then((value) => database = value);
}
Future<Database> getConnection() async {
return await openDatabase('ims.db');
}
}
All I have done, is used the callback method to assign the value when the value is available.
Here's a solution based on staggering the start of the async function with start times at least 1 second apart, when calls come in almost simultaneously.
Steps:
Use the lastKnownTime to calculate the delta, where the initial value is 0
Once the delta is not some huge number, you know it's a duplicate call.
class StartConversationState extends State<StartConversationStatefulWidget> {
#override
Widget build(BuildContext context) {
_delayPush(); // this is the call that gets triggered multiple times
}
int lastKnownTime = 0;
int delayMillis = 3000;
_delayPush() async {
delayMillis += 1500;
await new Future.delayed(Duration(milliseconds: delayMillis));
int millisSinceEpoch = new DateTime.now().millisecondsSinceEpoch;
int delta = millisSinceEpoch - lastKnownTime;
// if delta is less than 10 seconds, means it was a subsequent interval
if (delta < 10000) {
print('_delayPush() , SKIPPING DUPLICATE CALL');
return;
}
// here is the logic you don't want to duplicate
// eg, insert DB record and navigate to next screen
}

When exactly do we use async-await and then?

I am very confused about this. I request you to clarify the concept.
Consider the following scenarios:
Case 1:
int number = 0;
void calculate() {
number = number + 2;
print(number);
}
I know this works just fine. "2" will be printed on the terminal.
But why shouldn't I use async-await here, like this:
int number = 0;
void calculate() async {
void addition() async {
number = number + 2;
}
await addition();
print(number);
}
This seems logical to me, since print(number) should wait for number = number + 2 to finish. Why isn't this necessary? How does dart know which operation to execute first?
How is it ensured that print(number) isn't executed before number = number + 2 and "0" is printed on the terminal?
Does the sequence in which we write these operations in the function matter?
Case 2:
Consider the case where I am interacting with SQFLite database and values fetched depend on each other.
Note: number1, number2, number3 will still have values before the following function is called.
void getValues() async {
void calculate1() {
number1 = await db.getNumber1(10);
}
void calculate2() {
number2 = await db.getNumber2(number1);
}
await calculate1().then((_) async {
await calculate2().then((_) async {
number3 = await db.getNumber3(number2);
});
});
}
I have a lot of these types of functions in my app and I am doing this everywhere.
I am kind of paranoid, thinking if old values of number1and number2 are taken as a parameter in getNumber2() and getNumber3() respectively, then I'll be doomed.
async/await are just syntax sugar for the underlying Future framework. 95% of the time, they will suffice, and are preferred by the style guide.
One exception is that you may have multiple futures that you want to wait until all are complete in parallel. In that case, you'll need to use Future.wait([future1, future2, future3]), which cannot be expressed using await.
Dart is executed line by line. So when the function is called calculation will be done first then it will be printed. So you will always get 2 printed
You can see it like there is one main thread in general which is the UI thread. Any operations you are writing in this thread will be performed line by line and after completely executing one line it will move to next line.
Now suppose you have something which you know that it will take time to be computed or fully executed with either a result or error. If you will write this in the main UI thread (synchronous thread) that means you're stopping the UI of the app, which in turn makes the app to crash(Application Not Responding Error) as the operating system feels that the app has frozen but as you know this is happening because of the compute you are running in the UI thread which is taking time and the UI is waiting for it to be completely executed.
So to overcome this issue we use Asynchronous methods to compute the time taking computations like getting some data from a database which will return a value or error in "future". The main UI thread doesn't waits for the asynchronous threads. If you don't have anything to show to the user until any asynchronous task is completed you place the loading indicators for the time being.
Hope this helps!

How to block until an async function completes [duplicate]

I'm on the way to evaluate Dart for a German company by porting various Java programs to Dart and compare and analyze the results. In the browser Dart wins hands down. For server software performance seemed to be a serious isssue (see this question of me) but that got mostly defused.
Now I'm in the area of porting some "simple" command-line tools where I did not expect any serious problems at all but there is at least one. Some of the tools do make HTTP requests to collect some data and the stand-alone Dart virtual machine only supports them in an asynchronous fashion. Looking through all I could find it does not seem to be possible to use any asynchronous call in a mostly synchronous software.
I understand that I could restructure the available synchronous software into an asynchronous one. But this would transform a well-designed piece of software into something less readable and more difficult to debug and maintain. For some software pieces this just does not make sense.
My question: Is there an (overlooked by me) way to embed an asynchronous call into a synchronously called method?
I imagine that it would not be to difficult to provide a system call, usable only from within the main thread, which just transfers the execution to the whole list of queued asynchronous function calls (without having to end the main thread first) and as soon as the last one got executed returns and continues the main thread.
Something which might look like this:
var synchFunction() {
var result;
asyncFunction().then(() { result = ...; });
resync(); // the system call to move to and wait out all async execution
return result;
}
Having such a method would simplify the lib APIs as well. Most "sync" calls could be removed because the re-synchronisation call would do the job. It seems to be such a logical idea that I still think it somehow exists and I have missed it. Or is there a serious reason why that would not work?
After thinking about the received answer from lm (see below) for two days I still do not understand why the encapsulation of an asynchronous Dart call into a synchronous one should not be possible. It is done in the "normal" synchronous programing world all the time. Usually you can wait for a resynchronization by either getting a "Done" from the asynchronous routine or if something fails continue after a timeout.
With that in mind my first proposal could be enhanced like that:
var synchFunction() {
var result;
asyncFunction()
.then(() { result = ...; })
.whenComplete(() { continueResync() }); // the "Done" message
resync(timeout); // waiting with a timeout as maximum limit
// Either we arrive here with the [result] filled in or a with a [TimeoutException].
return result;
}
The resync() does the same that would normally happen after ending the main method of an isolate, it starts executing the queued asynchronous functions (or waits for events to make them executable). As soon as it encounters a continueResync() call a flag is set which stops this asynchronous execution and resync() returns to the main thread. If no continueResync() call is encountered during the given timeout period it too aborts the asynchronous execution and leaves resync() with a TimeoutException.
For some groups of software which benefit from straight synchronous programing (not the client software and not the server software) such a feature would solve lots of problems for the programer who has to deal with asynchrounous-only libraries.
I believe that I have also found a solution for the main argument in lm's argumentation below. Therefore my question still stands with respect to this "enhanced" solution which I proposed: Is there anything which really makes it impossible to implement that in Dart?
The only time that you can wrap an async method in a synchronous one is when you don't need to get a return value.
For example if you want to disable the save button, save results to the server asynchronously and re-enable the save button when the job is done you can write it like this:
Future<bool> save() async {
// save changes async here
return true;
}
void saveClicked() {
saveButton.enabled = false;
save()
.then((success) => window.alert(success ? 'Saved' : 'Failed'))
.catchError((e) => window.alert(e))
.whenComplete(() { saveButton.enabled = true; });
}
Note that the saveClicked method is fully synchronous, but executes the save method asynchronously.
Note that if you make saveClicked async, not only do you have to call it using the async pattern, but the entire method body will run asynchronously so the save button will not be disabled when the function returns.
For completeness the async version of saveClicked looks like this:
Future<Null> saveClicked() async {
saveButton.enabled = false;
try {
bool success = await save();
window.alert(success ? 'Saved' : 'Failed');
}
catch (e) {
window.alert(e);
}
finally {
saveButton.enabled = true;
}
}
Yes, this is way late, but I think this is a cool feature new people should know about.
There is a way, but the Dart docs warn against it (and it's somehow "experimental", although the implications aren't really discussed).
The waitFor command.
You basically pass in an asynchronous function that returns a Future, an optional timeout parameter, and the waitFor function will return the result.
For example:
final int number = waitFor<int>(someAsyncThatReturnsInt);
The resync function cannot be implemented in Dart's current execution model.
Asynchronous execution is contagious. A synchronous function must return before any other asynchronous events can execute, so there is no way to synchronously wait for asynchronous execution.
Execution in Dart is single-threaded and event based. There is no way for the resync function to block without it also blocking all other execution in the same isolate, so the pending async operations will never happen.
To block the synchronous execution, and continue executing something else, you need to preserve the entire call stack up to that point, and reinstate it later when the synchronous operations have completed. If you have that functionality, then there are probably better ways to do things than Future and Stream :)
Also, waiting for "all async execution" isn't well-defined in an event based system. There might be a broadcast Stream emitting events coming in from the network, a periodic timer, or a receive port getting data from another isolate, or some other source of events that you can't wait for because they come from outside the isolate, or event the process. When the current isolate shuts down, it might send a final shut-down message to another isolate, so effectively the "async execution" isn't over until the isolate dies.
Using the async/await syntax, you won't get synchronous operation, but it will be easier to code the similar asynchronous operation:
function() async {
var result = await asyncFunction();
return result;
}
It won't wait for async operations that aren't reflected in the Future returned by asyncFunction, but that's the job of asyncFunction to not complete until its operations are complete.
Dart is inherently async. Trying to avoid asynchronity won't work out.
There are sync versions of some API calls for example in dart:io and in some situations it might seem simpler to use them instead but because there aren't sync versions for all methods/functions you can't avoid async entirely.
With the recent introduction of the async/await feature programming async become much simpler and the code looks almost like sync code (but it isn't).
If a call went async it stays async. As far as I know there is nothing you can do about it.
import 'package:synchronized_lite/synchronized_lite.dart';
import 'dart:async';
// Using Lock as a mixin to further mimic Java-style synchronized blocks
class SomeActivity with Lock {
bool _started = false;
Future<bool> start() async {
// It's correct to return a Future returned by synchronized()
return synchronized(() async {
if(_started)
return false;
// perform the start operation
await Future.delayed(Duration(seconds: 1));
print("Started");
_started = true;
return true;
});
}
Future<void> stop() async {
// It's also correct to await a synchronized() call before returning
// It's incorrect to neither await a synchronized() call nor return its Future.
await synchronized(() async {
if(!_started)
return;
// perform the stop operation`enter code here`
await Future.delayed(Duration(seconds: 1));
print("Stopped");
_started = false;
});
}
}
// Prints:
// Started
// Stopped
main() async {
var a = SomeActivity();
print("Hello");
a.start();
a.start();
a.stop();
await a.stop();
}
/*Since the Await statement can be used in only asynchronous methods. Then we do two methods.I thinking first we call the async method and then we constantly query the null result for the non-async method. Then we get a synchronized model. In this way, we will wait for the answer in the non-async method. Such a method comes to my mind. But as far as I can see, there is no escape from the async working model in flutter dart language. Need to get used to it.It may be unprofessional, but I wanted to share the solution that came to my mind. hope it helps.
Stock resultStockQueryByBarcodeAsync;
bool waitStockQueryByBarcodeAsyncCompleted = false;
Stock WaitStockQueryByBarcodeAsync(String barcode, int timeOut) {
CallStockQueryByBarcodeAsync(barcode);
var startTime = new DateTime.now();
while (!waitStockQueryByBarcodeAsyncCompleted) {
Duration difference = DateTime.now().difference(startTime);
if (difference.inMilliseconds > timeOut) {
throw TimeoutException("Timeout Exceeded");
}
//we must scope time. Because it can be enter endless loop.
}
return resultStockQueryByBarcodeAsync;
}
void CallStockQueryByBarcodeAsync(String barcode) async {
waitStockQueryByBarcodeAsyncCompleted = false;
resultStockQueryByBarcodeAsync = null;
var stock = await StockQueryByBarcodeAsync(barcode);/*your target async method*/
waitStockQueryByBarcodeAsyncCompleted = true;
resultStockQueryByBarcodeAsync = stock;
}
In my case, I had to initialize the database connection from constructor. I am pretty new in Flutter and I don't know what are the best practices right now. But, here is what I did.
class Storage {
late Database database;
Storage() {
getConnection().then((value) => database = value);
}
Future<Database> getConnection() async {
return await openDatabase('ims.db');
}
}
All I have done, is used the callback method to assign the value when the value is available.
Here's a solution based on staggering the start of the async function with start times at least 1 second apart, when calls come in almost simultaneously.
Steps:
Use the lastKnownTime to calculate the delta, where the initial value is 0
Once the delta is not some huge number, you know it's a duplicate call.
class StartConversationState extends State<StartConversationStatefulWidget> {
#override
Widget build(BuildContext context) {
_delayPush(); // this is the call that gets triggered multiple times
}
int lastKnownTime = 0;
int delayMillis = 3000;
_delayPush() async {
delayMillis += 1500;
await new Future.delayed(Duration(milliseconds: delayMillis));
int millisSinceEpoch = new DateTime.now().millisecondsSinceEpoch;
int delta = millisSinceEpoch - lastKnownTime;
// if delta is less than 10 seconds, means it was a subsequent interval
if (delta < 10000) {
print('_delayPush() , SKIPPING DUPLICATE CALL');
return;
}
// here is the logic you don't want to duplicate
// eg, insert DB record and navigate to next screen
}

Vertx Future Object returns null

public Future<String> getString(){
Future<String> data = Future.future();
postgreSQLClient.query("select * from test", resultSetAsyncResult -> {
if(resultSetAsyncResult.succeeded()){
List<JsonObject> rows = resultSetAsyncResult.result().getRows();
data.complete("Completed...");
}
});
return data;
}
Future<String> future = getString();
System.out.println(future.result());
This Return's null. Am I doing anything wrong here? I did also try AtomicReference, it returns null too. Confused.
Vert.x Future, unlike Java Future, are not blocking.
In other words, when you write future.get() with a Java Future, it blocks the caller until the future completes, while future.result() with a Vert.x Future returns immediately, whether or not the future is completed.
Vert.x Future are not blocking because Vert.x code runs on event loops which must never be blocked.
If you want the result, set a handler
future.setHandler(ar -> {
if (ar.succeeded()) {
// get ar.result()
} else {
// deal with ar.cause()
}
});