"Event source 1" -> "Wait for\nan event\nto happen"
"Event source 2" -> "Wait for\nan event\nto happen"
- "Event source n" -> "Wait for\nan event\nto happen"
+ "Event source N" -> "Wait for\nan event\nto happen"
"Wait for\nan event\nto happen" -> "Handle an\nevent" [label="Something happened...\n", tailport="n", headport="n"]
"Handle an\nevent" -> "Wait for\nan event\nto happen" [tailport="s", headport="s"]
--- /dev/null
+
+digraph G {
+ rankdir = LR
+
+ node
+ [
+ fontname = "Inconsolata"
+ fontsize = 20
+ shape = record
+ style = rounded
+ margin = "0.2,0.2"
+ ]
+
+ edge
+ [
+ fontname = "Inconsolata"
+ fontsize = 18
+ arrowhead = vee
+ arrowtail = vee
+ arrowsize = 2
+ ]
+
+ "Event source 1" -> "Wait for\nan event\nto happen"
+ "Event source 2" -> "Wait for\nan event\nto happen"
+ "Event source N" -> "Wait for\nan event\nto happen"
+
+ "Wait for\nan event\nto happen" -> "Demultiplex and\ndispatch events" [tailport="n", headport="n"]
+ "Demultiplex and\ndispatch events" -> "Wait for\nan event\nto happen" [tailport="s", headport="s"]
+
+ "Demultiplex and\ndispatch events" -> "Event handler 1"
+ "Demultiplex and\ndispatch events" -> "Event handler 2"
+ "Demultiplex and\ndispatch events" -> "Event handler M"
+
+
+ "Demultiplex and\ndispatch events" [style="rounded,filled",fillcolor="#FFFF88"]
+}
+
print($pizza);
```
+???
+But some programs are long-lived.
+
---
## Event-driven programs
But there are some complications and things to knows, which is why this talk exists.
---
+name: graph-eventloop
class: center, middle
+## Event loop
+
![Event loop](img/eventloop.svg)
???
### syscalls
- [`pause`](http://man.he.net/man2/pause) - Sleeps until signal
+
+--
- [`select`](http://man.he.net/man2/select), [`poll`](http://man.he.net/man2/poll), [`epoll`](http://man.he.net/man7/epoll), [`kqueue`](https://www.freebsd.org/cgi/man.cgi?format=ascii&sektion=2&query=kqueue) - Monitor multiple file descriptors
+
+--
- [`clock_gettime`](http://man.he.net/man2/clock_gettime) - What time is it now?
+---
+
+## Reactor pattern
+
+.big[
+- Queues events asynchronously.
+- Demultiplexes and dispatches synchronously.
+]
+
+---
+name: graph-reactor
+class: center, middle
+
+## Reactor pattern
+
+![Reactor](img/reactor.svg)
+
---
class: ex-basicreactor
}
```
+---
+class: ex-basicreactor
+
+## The basic reactor
+
+```perl
+our $timers = [...];
+our $io_handles = [...];
+
+while (1) {
+ my $next_timer = find_next_timer($timers);
+
+* poll($io_handles, $next_timer->time_from_now);
+
+ handle_ready_io_handles($io_handles);
+ handle_expired_timers($timers);
+}
+```
+
---
## Reactor examples on CPAN
- [`Mojo::Reactor::Poll`](https://metacpan.org/source/Mojo::Reactor::Poll)
]
+---
+class: center, middle
+
+## Use [`Future::AsyncAwait`](https://metacpan.org/pod/Future::AsyncAwait).
+
+???
+If you have used JavaScript recently, you may have used its "async/await" feature to clean up your non-blocking code.
+
+---
+class: center, middle
+
+### Yes, Perl can do it, too!
+
+---
+class: ex-asyncawait
+
+## Without async and await
+
+```perl
+use Future;
+
+sub do_two_things {
+ return do_first_thing()->then(sub {
+ my $first = shift;
+
+ return do_second_thing($first)->then(sub {
+ my $second = shift;
+
+ return Future->done([$first, $second]);
+ });
+ });
+}
+```
+
+---
+class: ex-asyncawait
+
+## With async and await
+
+```perl
+use Future::AsyncAwait;
+
+async sub do_two_things
+{
+ my $first = await do_first_thing();
+
+ my $second = await do_second_thing($first);
+
+ return [$first, $second];
+}
+```
+
+???
+There are caveats: Localized variable assignments don't work, nor anything that has implied local-like behavior.
+---
+
+## Events in the world
+
+
+
---
class: center, middle
name: conclusion