]> Dogcows Code - chaz/talk-event-driven-programming-in-perl/commitdiff
add more slides on Future
authorCharles McGarvey <cmcgarvey@bluehost.com>
Mon, 18 Jun 2018 06:48:44 +0000 (00:48 -0600)
committerCharles McGarvey <cmcgarvey@bluehost.com>
Mon, 18 Jun 2018 06:48:44 +0000 (00:48 -0600)
css/slides.css
notes.txt
slides.html

index eb366c3b177756aaecf1ff211e075b7364c3d753..accda7150bb2a4d6075ca3c9161dc01bdedee63b 100644 (file)
     font-size: 38px;
 }
 
+.ex-debugging .bash {
+    font-size: 38px;
+}
+
+.ex-future .perl {
+    font-size: 32px;
+}
+
+.ex-future2 .perl {
+    font-size: 24px;
+}
 
index 6b732a6f54b44de687634bea5df81339c0a1ffbe..8a43724edef2ca8037cd3dcd3afd43cbff999352 100644 (file)
--- a/notes.txt
+++ b/notes.txt
@@ -13,18 +13,19 @@ X User input
 X Signal
 X Anything that can spontaneously happen in the real world.
 
-3. How to write a modern event-loop.
+3. How to write a modern event-loop (reactor style).
 X kernel facilities (poll, select, etc.)
 
-4. List of already-built event loops.
-- EV
-- Glib
+4. List of already-built reactors.
+X EV
+X Glib
+X ...
 
 5. Event-driven programming in Perl
-- POE
 - AnyEvent
 - IO::Async
 - Mojo::IOLoop
+- POE
 
 6. Special considerations
 X Exceptions in event-driven code.
@@ -33,9 +34,9 @@ X SIGPIPE, EPIPE - might have more to do with long-lived processes rather than
 X You should almost always check the return code of your syscalls to see if they succeeded or not.
 
 7. Promises:
-- Future
-- Future::AsyncAwait
-- Future::Utils
+X Future
+X Future::AsyncAwait
+X Future::Utils
 
 8. Real-world uses for event-driven applications:
 - Webhooks
@@ -51,13 +52,13 @@ X What is event-driven programming?
   demultiplex them, delivering them to appropriate handlers.
 - C10k problem
 - EDA (event-driven architecture)
-- Benefits of Event-driven
-- How to debug event-driven code.
+X Benefits of Event-driven
+X How to debug event-driven code.
 
 Traditional programs:
 - CGI - web server calls your program, and your program does its thing and
   finishes.
-- filters - grep, less, sed, etc. Like a function, the program takes its input
+X filters - grep, less, sed, etc. Like a function, the program takes its input
   and produces some output.
 
 Perl features:
index 8904bd24addaf2a9151822c1795c18636db47498..161851a13bf2d9f2c16eb9e5a8068a2ae94d68cc 100644 (file)
@@ -464,7 +464,6 @@ while (1) {
 ```
 
 ---
-
 ## Reactor examples on CPAN
 
 .big[
@@ -480,6 +479,64 @@ while (1) {
 These links, which will be available to you with the slides, link directly to the source code of these modules on
 metacpan so you can take a look at how they work.
 
+---
+## Reactors
+
+.col.big[
+- [`Cocoa::EventLoop`](https://metacpan.org/pod/Cocoa::EventLoop)
+- [`EV`](https://metacpan.org/pod/EV)
+- [`Event::Lib`](https://metacpan.org/pod/Event::Lib)
+- [`Event`](https://metacpan.org/pod/Event)
+- [`FLTK`](https://metacpan.org/pod/FLTK)
+]
+.col.big[
+- [`Glib`](https://metacpan.org/pod/Glib), [`Gtk`](https://metacpan.org/pod/Gtk), [`Gtk2`](https://metacpan.org/pod/Gtk2)
+- [`Tk`](https://metacpan.org/pod/Tk)
+- [`UV`](https://metacpan.org/pod/UV)
+- [`Wx`](https://metacpan.org/pod/Wx)
+- probably more...
+]
+
+???
+I'm not going to go over any of these.
+
+- You can use any one of these directly.
+- Some of that are better than others (obvious).
+- Which one you choose may depend one what you're building.
+  - If you're building a GUI, your choice is made for you.
+  - High-concurrency network application, `EV` is a good choice.
+
+But actually you may not need to pick one...
+
+---
+class: center, middle
+
+## Reactor "front ends"
+
+???
+By my count there are four main front ends.
+
+---
+## Reactor "front ends"
+
+.big[
+- [**`POE`**](https://metacpan.org/pod/POE) - Portable multitasking and networking framework for any event loop (or Perl, Objects, and Events)
+- [**`IO::Async`**](https://metacpan.org/pod/IO::Async) - Asynchronous event-driven programming
+- [**`Mojo::IOLoop`**](https://metacpan.org/pod/Mojo::IOLoop) - Minimalistic event loop
+- [**`AnyEvent`**](https://metacpan.org/pod/AnyEvent) - The DBI of event loop programming
+]
+
+???
+The benefit of using one of these rather than the reactors themselves is that your code will automatically work with any
+of a number of supported reactors.
+
+POE:
+- The oldest, released 1998
+- Parallel processing was it's primary use.
+- Everything center by the "wheel" (loop).
+- You add "handles" to the object.
+- Each type of handle has certain events it knows how to handle.
+
 ---
 name:  not-all-roses
 class: center, middle
@@ -530,6 +587,9 @@ $promise->on_done(sub { ... });
 $promise->on_fail(sub { ... });
 ```
 
+???
+More on this later.
+
 ---
 class: center, middle
 
@@ -566,7 +626,152 @@ Look for `EPIPE` from syscalls (like [`write`](http://man.he.net/man2/write)) in
 ---
 class: center, middle
 
-## Use [`Future::AsyncAwait`](https://metacpan.org/pod/Future::AsyncAwait).
+## Debugging event-driven code
+
+---
+class: ex-debugging
+
+## Debugging event-driven code
+
+.big[
+- Print debug info to `STDERR`.
+]
+
+```bash
+export PERL_FUTURE_DEBUG=1
+# and
+export ANYEVENT_DEBUG=8
+# or
+export MOJO_IOLOOP_DEBUG=1
+# etc.
+```
+
+---
+## Debugging event-driven code
+
+.big[
+- Print debug info to `STDERR`.
+- Check out [`AnyEvent::Debug`](https://metacpan.org/pod/AnyEvent::Debug).
+]
+
+---
+## Debugging event-driven code
+
+.big[
+- Print debug info to `STDERR`.
+- Check out [`AnyEvent::Debug`](https://metacpan.org/pod/AnyEvent::Debug).
+- Use [`perl5db.pl`](https://metacpan.org/pod/perl5db.pl) and other `Devel::` debuggers.
+]
+
+???
+Traditional debuggers are still useful for event-driven code.
+- Be sure to carefully avoid memory leaks -- they are more devastating in long-lived programs which event-driven
+programs tend to be.
+
+---
+class: center, middle
+
+## Promises:
+### Proxy objects for future values
+
+???
+Proxy objects for values that have not yet been retrieved or computed.
+
+- In some cases, promises can provide you an alternative, often more useful interface to callbacks.
+
+---
+class: ex-future
+
+## Basic usage (using [`Future`](https://metacpan.org/pod/Future))
+
+```perl
+my $future = fetch_remote_file($url);
+
+$future->on_done(sub($filename, $contents) {
+    print "Fetched $filename\n";
+});
+```
+
+???
+The future is an object that stands in for the thing we actually want until the thing we want is available.
+
+--
+```perl
+$future->on_fail(sub($error) {
+    warn $error;
+});
+```
+
+???
+If the operation that provides the `Future` isn't able to fulfill its promise to provide us what we want, the `Future`
+may be set to a "fail" state.
+
+- For any operation that can fail (and that includes almost everything), it's a good idea to handle errors.
+
+---
+class: ex-future
+
+## Chaining futures
+
+```perl
+my $future = fetch_remote_file($url)
+    ->then(sub($filename, $contents) {
+        my $another_future = write_local_file("/tmp/$filename",
+                                              $contents);
+        return $another_future;
+    });
+
+$future->on_done(sub($filepath) {
+    print "Saved file to $filepath\n";
+});
+
+$future->on_fail(sub($error) {
+    warn $error;
+});
+```
+
+---
+class: ex-future2
+
+## Creating futures
+
+```perl
+use AnyEvent::HTTP;
+use Future;
+
+sub fetch_remote_file($url) {
+    my $future = Future->new;
+
+    http_get $url => sub($data, $headers) {
+        if ($headers->{Status} =~ /^[23]/) {
+            my ($filename) = get_filename($headers);
+            $future->done($filename, $data);
+        }
+        else {
+            $future->fail("Failed to fetch file: $headers->{Reason}");
+        }
+    };
+
+    return $future;
+}
+```
+
+---
+class: center, middle
+
+Check out [Paul Evan's blog](http://leonerds-code.blogspot.com/2013/12/futures-advent-day-1.html) for more things you can do with `Future`s.
+
+And, of course, [read the pod](https://metacpan.org/pod/Future).
+
+???
+Paul did an advent calendar with short posts detailing the things you can do with `Future`.
+
+- It's really well done.
+
+---
+class: center, middle
+
+## There's also [`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.
@@ -617,11 +822,46 @@ async sub do_two_things
 
 ???
 There are caveats: Localized variable assignments don't work, nor anything that has implied local-like behavior.
+
 ---
+class: center, middle
 
-## Events in the world
+## Finally, there's also [`Future::Utils`](https://metacpan.org/pod/Future::Utils).
+
+---
+class: ex-future2
 
+## Call
 
+```perl
+my $future = call {
+    do_stuff();
+
+    ...
+
+    my $future = ...;
+    return $future;
+};
+```
+
+Any exceptions throw in the code block are caught and become a failed `Future`.
+
+---
+class: ex-future2
+
+## Loops and stuff
+
+```perl
+use Future::Utils qw(repeat);
+
+my $eventual_future = repeat {
+   my $trial_future = ...
+   return $trial_future;
+} while => sub($last_trial_future) { return should_keep_going($last_trial_future) };
+```
+
+---
+## Events in the world
 
 ---
 class: center, middle
This page took 0.03052 seconds and 4 git commands to generate.