1

I have a program that essentially has two events:

  • EventOne: query from a REST API every minutes and get a number
  • EventTwo: show the number from EventOne on an LED screen

The dilemma is:

  • EventOne's REST API is slow, it might take a few seconds to load
  • EventTwo uses LED screen's driver function, it has to be kept running (with perhaps only millisecond-level interval) for the LED screen to refresh fast enough, meaning that I can't get it blocked by a few seconds; otherwise the LED shows broken number.

What I think I need is an async HTTP I/O just like JavaScript's async/await syntax so that I can "pause" my EventOne after firing the HTTP request before I get the number back and run my EventTwo in between. When the async IO is ready, EventOne can be resumed.

Is this something libevent natively support? If not, is there any similar event loop framework that natively supports this?

Note:

  1. The current program I have uses a multi-threaded model, which works fine. The purpose of this question is to investigate the feasibility of using event loop to achieve the same.
D.J. Elkind
  • 367
  • 2
  • 8

1 Answers1

1

What I think I need is an async HTTP I/O just like JavaScript's async/await syntax so that I can "pause" my EventOne after firing the HTTP request before I get the number back and run my EventTwo in between. When the async IO is ready, EventOne can be resumed.

What you are describing as "events" is not at all what libevent means by the term. You've described actions that your program may take, but an event is something outside the normal flow of your program, to which your program (maybe) responds.

You've described your program actions in terms of their frequency, so probably some of the events your program would be interested in would be timers firing. I guess you would have a rapid timer and a slow timer. When the rapid timer fires (this is an event) your program runs the driver function to refresh the screen, and (if necessary) resets the timer. When the slow timer fires (this is a different event), your program sends the REST request.

But there is also at least one other event in which you are interested: the REST response arrives, or at least the socket on which you expect it is or becomes readable. Then and only then, you read the available data from the socket and process it.

That's basically how I/O multiplexing works. You service clients / devices when and only when they are ready, typically using interfaces such as read() and write() that will not block as long as they can make some progress, and keep track of where you are on a per-client basis. By avoiding trying to read from or write to devices that are not ready, the process will not block on I/O when there is any work it can perform.

Is this something libevent natively support?

Yes, this is the main thing libevent is designed for. I/O multiplexing especially, though my understanding is that it also integrates handling for timer events, among other things.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • I guess I know roughly what you mean, but I am not sure if libevent provides functions for this. The rapid timer's cb is fine, the problem is in the slow timer's callback. Currently I use libcurl to query the result, which is synchronous. How can I make this asynchronous? or how can I make the "HTTP reqeust part" of libcurl an event, and make the "HTTP response part" another event? – D.J. Elkind May 31 '23 at 05:53
  • 1
    @D.J.Elkind, you would likely need to use libcurl differently than you do now, but it does support asynchronous and incremental operation modes that I anticipate could work here. See [libcurl-multi](https://curl.se/libcurl/c/libcurl-multi.html). – John Bollinger May 31 '23 at 12:18