Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZeroMQ seems to "wait" one second before receiving data. #4

Open
Eerey opened this issue Feb 13, 2022 · 17 comments
Open

ZeroMQ seems to "wait" one second before receiving data. #4

Eerey opened this issue Feb 13, 2022 · 17 comments

Comments

@Eerey
Copy link

Eerey commented Feb 13, 2022

Hello there,

I'm testing this feature on windows.
When using a push/pull or pub/sub pattern there seems to be a one second delay on the pull/sub socket.
Is it built into ZeroMQ or can i configure this behaviour?

Best regards

@Eerey
Copy link
Author

Eerey commented Feb 13, 2022

Oh, i see, it is here:

zeromq.dart

  /// Starts the periodic polling task if it was not started already and
  /// if there are actually listeners on sockets
  void _startPolling() {
    if (_timer == null && _listening.isNotEmpty) {
      _timer = Timer.periodic(const Duration(seconds: 1), (timer) => _poll());
    }
  }

this should be configurable imo. Is there a particular reason to limit it to 1 second?
Best regards and thanks for the plugin, I might use it for a project

@Eerey Eerey changed the title ZeroMQ seems to "wait" one second before sending data. ZeroMQ seems to "wait" one second before receiving data. Feb 13, 2022
@enwi
Copy link
Owner

enwi commented Feb 15, 2022

this should be configurable imo. Is there a particular reason to limit it to 1 second? Best regards and thanks for the plugin, I might use it for a project

No there is no particular reason. I thought 1 second should be enough for most applications, but making it configurable seems to be the best option here.

Since you already invested some time, do you want to open a PR and make it configurable?

@Eerey
Copy link
Author

Eerey commented Feb 15, 2022

Will take a while but i can look into it :)

@enwi
Copy link
Owner

enwi commented Mar 20, 2022

On another note, I was thinking about using another thread just for the ZeroMQ poller. Then we could let it wait without delay and have messages coming in at the quickest rate possible. Though I don't know if that is a good idea.
https://pub.dev/documentation/threading/latest/

@Eerey
Copy link
Author

Eerey commented Mar 23, 2022

@enwi that sounds like a great idea. Can this be done with isolates? Do isolates behave the same on every platform?

@enwi
Copy link
Owner

enwi commented Mar 27, 2022

@Eerey It should be possible to do it with isolates as well. The main difference between isolates and threads being that isolates do not share memory as threads do.
https://itnext.io/minimalist-guide-to-isolates-in-dart-flutter-dd5bdee031e

@ach-ee
Copy link

ach-ee commented Apr 18, 2022

I have implemented asynchronous polling on my fork. You can check it out on this PR. The main change is the ZPoller class and the original Timer implementation has been removed from ZContext.

It works similar to other ZeroMQ implementations - the poller runs on another thread (Isolate in this case) and updates the main thread if there is data available. ZSockets are still updated through their Streams as soon as data is available.

It works well on Linux and I will test it out on Windows soon when I get a chance. I'm fairly new to Dart, so let me know if you have any suggestions for improvements.

@enwi
Copy link
Owner

enwi commented Apr 26, 2022

Great job on using an isolate to solve this issue @ach-ee 👍
Could you open a PR?

Also what is you opinion on this https://dart.dev/guides/libraries/create-library-packages#organizing-a-library-package?

@enwi
Copy link
Owner

enwi commented Jul 19, 2022

@ach-ee Do you have any updates on your changes regarding opening a new PR?

@rbebb
Copy link

rbebb commented Jul 28, 2022

@ach-ee I would also like to know if there are any updates on opening a PR for this! I also noticed you made a few other changes in your fork that would be great to include in this library👍🏼

@stevenlayne12
Copy link

Hey @enwi, is there a short term fix I can do on my end? I tried using @ach-ee fork but I am afraid getting all this to work is above my paygrade as a flutter novice.

@enwi
Copy link
Owner

enwi commented Jan 24, 2023

Hey @stevenlayne12 sure there is some kind of workaround by changing the polling interval. Though this could lead to performance issues on some phones, but I am not sure.

Just change the interval here:

_timer = Timer.periodic(const Duration(seconds: 1), (timer) => _poll());

@stevenlayne12
Copy link

stevenlayne12 commented Jan 28, 2023

Okay awesome thanks @enwi !

As a separate point, I am trying to achieve low latency communication between flutter and python on linux (and optionally windows just for testing) and landed on using the PAIR socket type because I am looking for low latency bidirectional communication between those two stacks. Does this sound like the way to go? I only ask because I am not sure if this polling issue is partly due to the choice of socket in my case or not

Nevertheless, I will give your suggestion a go! 👍

@enwi
Copy link
Owner

enwi commented Feb 10, 2023

@stevenlayne12 the polling approach is currently not the best way to go @ach-ee started working on letting the ZeroMQ code run in another thread, which would be a lot better and have less latency, but I guess he stopped working on that. The code is still available on his GitHub though if you want to have a look.

@enwi
Copy link
Owner

enwi commented Mar 20, 2023

@canders-rf you can take a look at what @ach-ee did, which is currently in an unfinished state, but essentially the polling loop should be moved into a separate thread so that it can poll with blocking instead of right now where it would hang the whole app.

@DonggeonKim1012
Copy link

Hi @enwi ,
I know you've been asked about this too many times, but I could really use some help.
I'm trying to implement a simple dart req client - python rep server pattern.
I've encountered the error 'Operation cannot be accomplished in current state' like many others.

What I'm curious is:

  1. You've mentioned above that the short fix is changing the interval of the polling, but to how many seconds?
  2. ach-ee's fix seems finished. His 'poller.dart' includes the ZPoller wrapper, the _poll function which runs on isolates, and the _pollListener function which connects the main thread's ReceivePort to the isolate. However it still doesn't eliminate the error above, maybe there's something more to be done. I wonder what's your opinion on this?

Really admire the work you're doing. Thanks in advance.

@enwi
Copy link
Owner

enwi commented May 22, 2023

1. You've mentioned above that the short fix is changing the interval of the polling, but to how many seconds?

Less than 1 second, maybe half of that or even 200 or 100 ms.

2. ach-ee's fix seems finished. His 'poller.dart' includes the ZPoller wrapper, the _poll function which runs on isolates, and the _pollListener function which connects the main thread's ReceivePort to the isolate. However it still doesn't eliminate the error above, maybe there's something more to be done. I wonder what's your opinion on this?

It is unfinished, because the main thread is not communicating with the receiving thread if recall correctly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants