Add support for returning stream from an isolate - flutter

I have started using isolates and returned a value from my isolate as if it was a function.
Then I wanted to change the code to return stream, instead of future.
From this
compute<List<String>, List<String>>(
(params) async { ... return ...;
I wanted to change to this
compute<List<String>, Stream<String>>(
(params) async* { ... yield ...;
But I get the error:
The argument type 'Stream<FutureOr<Stream>>
Function(List)' can't be assigned to the parameter type
'FutureOr<Stream> Function(List)'. (Documentation)
If I understand correctly we can transfer data back "as stream" by opening ports and sending data through it.
Wouldn't it be better if the syntax will stay the same as "Stream function" and the implementation will do that for us?.
When opening ports you need to handle some extra staff like checking if the port is free and changing to a different port number if it doesn't.
Some extra explanation why opening a port is not needed when returning a single value and is needed when returning a stream will be welcome as well.
Should we ask for Dart team to make the change for isolates to support stream as well?.
Related to dart vm send back stream from isolate

I have found isolate_contactor package that can do that.
You can send results from inside the package isolate with
channel.sendResult()
Like a using a yield.

Related

neo4j using transactionListener causes read/write error

I'm trying to use TransactionEventListener in neo4j. There don't seem to be any lifecycle hooks for plugins, so I figure the only way to do it is to have a plugin procedure do it. However, trying to do that gives me this error:
Neo4jError: Writing in read access mode not allowed. Attempted write to internal graph 1 (system)
The plugin uses write mode, even if I'm not actually writing anything to the database; I'm just registering that TransactionEventListener, although that could indeed lead to writes later on. Still, I've got Write mode.
Here's my procedure:
#Procedure(name = "setTransactionListener", mode = Mode.WRITE)
public Stream<BuiltInProcedures.NodeResult> setTaxonomy(
#Name("taxonomy") Map<String, Map<String, Object>[]> taxonomy
) {
var managementService = new DatabaseManagementServiceBuilder(Path.of(".")).build();
var listener = new ValidationTransactionListener(taxonomy);
managementService.registerTransactionEventListener(db.databaseName(), listener);
return null;
}
Best guess is that I'm not supposed to register a transaction listener this way. But if not this way, then how? There don't seem to be any lifecycle hooks that get called when the database starts, so how can I possibly register an transactionEventListener?
Or is there a way I can give myself permission to do this?
What do you actually want to do?
It doesn't work like that, you need to register the listener in the database lifecycle within a KernelExtensionFactory?
See here for an example:
https://github.com/neo4j/apoc/blob/dev/common/src/main/java/apoc/ApocExtensionFactory.java#L53

How to make "compute()" function insert data to sqlite while in isolated process?

I'm working on flutter app that uses php apis for server and sqlite for local data.
The problem is with "compute()".
Here is the explanation :
I have three functions that receives data from api on the server, then add the data to my local database (sqlite) table.
First function to get data from server.
Future<List<Map<String, dynamic>>> getServerData(int vers)async {
//my code
}
Second function to insert data into local database:
Future<int> addNewData(List<Map<String, dynamic>>)async {
//my code
}
Third function to call the first and second function:
Future<bool> checkServerData(int vers)async {
List<Map<String, dynamic>> sdt= await getServerData(vers);
int res=await addNewData(sdt);
if(res>0) return true;
else return false;
}
I want to call the third function in a compute function:
compute(checkServerData, 2);
When did that I found this error:
null check operator used on null value.
Note*:
If I used it without calling local database it works good.
The error appears if I called the database to insert data into.
When I searched about this issue I found that it's not allowed to access any resources which generated in one thread from another thread. But I didn't understand exactly how to resolve it or how to use another way that do the same idea.
After searching about the issue specified, I found those workaround solutions:
1: if the process is very important to work in background, you can use the Isolate package classes and functions which allow all isolated processes or contexts to share data between them as messages sending and receiving. But it's something complex for beginners in flutter and dart to understand these things, except those who know about threading in another environments.
To now more about that I will list here some links:
Those for flutter and pub documentation:
https://api.flutter.dev/flutter/dart-isolate/dart-isolate-library.html
https://api.flutter.dev/flutter/dart-isolate/Isolate-class.html
https://pub.dev/packages/flutter_isolate
This is an example in medium.com website:
https://medium.com/flutter-community/thread-and-isolate-with-flutter-30b9631137f3
2: the second solution if the process isn't important to work on background:
using the traditional approaches such as Future.builder or async/await.
You can know more about them here:
https://www.woolha.com/tutorials/flutter-using-futurebuilder-widget-examples
https://dart.dev/codelabs/async-await
and you can review this question and answers in When should I use a FutureBuilder?

How to send message by message to Kafka

I'm new to reactive programming and I try to implement a very basic scenario.
I want to send a message to kafka each time a file is dropped to a specific folder.
I think that I don't understand well the basics things... so please could you help me?
So I have a few questions :
What is the difference between smallrye-reactive-messaging and smallrye-reactive-streams-operators ?
I have this simple code :
#Outgoing( "my-topic" )
public PublisherBuilder<Message<MessageWrapper>> generate() {
if(Objects.isNull(currentMessage)){
//currentMessage is an instance variable which is null when I start the application
return ReactiveStreams.of(new MessageWrapper()).map(Message::of);
}
else {
//currentMessage has been correctly set with the file information
LOGGER.info(currentMessage);
return ReactiveStreams.of(currentMessage).map(Message::of);
}
}
When the code goes in the if statement, everything is ok and I got a JSON serialization of my object will null values. However I don't understand why when my code goes to the else statement, nothing goes to the topic? It seems that the .of instructions of the if statement has broke the streams or something like that...
How to keep a continuous streams that 'react' to the new dropped files ? (or other events like HTTP GET request or something like that) ...
If I don't return an instance of PublisherBuilder but an Integer for example, then my kafka topic will be populated by a very huge stream of Integer value. This is why examples are using some intervals when sending messages...
Should I use some CompletationStage or CompletableFuture ? RxJAva2? It's a bit confusing which lib to use (vertx, smallrye, rxjava2, microprofile, ...)
What are the differences between :
ReactiveStreams.fromCompletionStage
ReactiveStreams.fromProcessor
ReactiveStreams.fromPublisher
ReactiveStreams.fromSubscriber
Which one to use on which scenario ?
Thank you very much !
Let's start with the difference between smallrye-reactive-messaging & smallrye-reactive-streams-operators: smallrye-reactive-streams-operators is the same as smallrye-reactive-messaging but in addition it has a support to MicroProfile-context-propagation. Since most reactive-messaging providers use Vert.x behind the scene, it will process your message in an event-loop style, which means it will run in separate thread. Sometimes you need to propagate some ctx from your base thread into the new thread (ex: populating CDI and Tx context to execute some JPA Entity manager logic). Here where ctx propagation help.
For method signatures. You can take a look at the official documentation of SmallRye-reactive-streams sections 3,4 & 5. Each one has a different use case. It is up to you which flavor do you want to use.
When to use what ? If you are not running within reactive context, you can use the below to send messages.
#Inject
#Channel("my-channel")
Emitter emitter;
For Message consumption you can use method signature like this :
#Incoming("channel-2")
public CompletionStage doSomething(Message anEvent)
Or
#Incoming("channel-2")
public void doSomething(String anEvent)
Hope that helps.

How to use delta trigger in flink?

I want to use the deltatrigger in apache flink (flink 1.3) but I have some trouble with this code :
.trigger(DeltaTrigger.of(100, new DeltaFunction[uniqStruct] {
override def getDelta(oldFp: uniqStruct, newFp: uniqStruct): Double = newFp.time - oldFp.time
}, TypeInformation[uniqStruct]))
And I have this error:
error: object org.apache.flink.api.common.typeinfo.TypeInformation is not a value [ERROR] }, TypeInformation[uniqStruct]))
I don't understand why DeltaTrigger need TypeSerializer[T]
and I don't know what to do to remove this error.
Thanks a lot everyone.
I would read into this a bit https://ci.apache.org/projects/flink/flink-docs-release-1.2/dev/types_serialization.html sounds like you can create a serializer using typeInfo.createSerializer(config) on your type info. Note what you're passing in currently is a type itself and NOT the type info which is why you're getting the error you are.
You would need to do something more like
val uniqStructTypeInfo: TypeInformation[uniqStruct] = createTypeInformation[uniqStruct]
val uniqStrictTypeSerializer = typeInfo.createSerializer(config)
To quote the page above regarding the config param you need to pass to create serializer
The config parameter is of type ExecutionConfig and holds the
information about the program’s registered custom serializers. Where
ever possibly, try to pass the programs proper ExecutionConfig. You
can usually obtain it from DataStream or DataSet via calling
getExecutionConfig(). Inside functions (like MapFunction), you can get
it by making the function a Rich Function and calling
getRuntimeContext().getExecutionConfig().
DeltaTrigger needs a TypeSerializer because it uses Flink's managed state mechanism to store each element for later comparison with the next one (it just keeps one element, the last one, which is updated as new elements arrive).
You will find an example (in Java) here.
But if all you need is a window that triggers every 100msec, then it'll be easier to just use a TimeWindow, such as
input
.keyBy(<key selector>)
.timeWindow(Time.milliseconds(100)))
.apply(<window function>)
Updated:
To have hour-long windows that trigger every 100msec, you could use sliding windows. However, you would have 10 * 60 * 60 windows, and every event would be placed into each of these 36000 windows. So that's not a great idea.
If you use a GlobalWindow with a DeltaTrigger, then the window will be triggered only when events are more than 100msec apart, which isn't what you've said you want.
I suggest you look at ProcessFunction. It should be straightforward to get what you want that way.

Set execution order of event-handlers of click event in jQuery?

I am using jQuery 1.9.1.
Suppose i have a button with id="clickMe"
My jQuery code is:
$('#clickMe').click(function(event)
{
eventHandler1();//do something
eventHandler2();//use output from eventHandler1() and do something
}
Now, i want "eventHandler2" to be executed at last so that i could use the output of "eventHandler1". Is there any way to do this manually and not just the way i have put the handlers inside the click event?
One more thing, "eventHandler1()" and "eventHandler2()" are present in different .js files and thus the requirement.
jQuery.when() provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events.
For example, when the Deferreds are jQuery.ajax() requests, the arguments will be the jqXHR objects for the requests, in the order they were given in the argument list.
$.when(eventHandler1).then(eventHandler2).done(function(){
alert('done.');
});
So can even use GLOBAL variable to store eventHandler1 output and access that inside eventHandler2
Example
var someVar;
function eventHandler1()
{
// process
someVar = some value from process
return someVar;
}
function eventHandler2()
{
alert(someVar);
}
Response to OP comment
as you have asked about execute handler in queue you can use Jai answer.
you can use .when .then and .done as below.
$.when(eventHandler1).then(eventHandler2).done(function(){
//process code
});