]> 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;
 }
 
     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.
 
 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.)
 
 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
 
 5. Event-driven programming in Perl
-- POE
 - AnyEvent
 - IO::Async
 - Mojo::IOLoop
 - AnyEvent
 - IO::Async
 - Mojo::IOLoop
+- POE
 
 6. Special considerations
 X Exceptions in event-driven code.
 
 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:
 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
 
 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)
   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.
 
 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:
   and produces some output.
 
 Perl features:
index 8904bd24addaf2a9151822c1795c18636db47498..161851a13bf2d9f2c16eb9e5a8068a2ae94d68cc 100644 (file)
@@ -464,7 +464,6 @@ while (1) {
 ```
 
 ---
 ```
 
 ---
-
 ## Reactor examples on CPAN
 
 .big[
 ## 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.
 
 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
 ---
 name:  not-all-roses
 class: center, middle
@@ -530,6 +587,9 @@ $promise->on_done(sub { ... });
 $promise->on_fail(sub { ... });
 ```
 
 $promise->on_fail(sub { ... });
 ```
 
+???
+More on this later.
+
 ---
 class: center, middle
 
 ---
 class: center, middle
 
@@ -566,7 +626,152 @@ Look for `EPIPE` from syscalls (like [`write`](http://man.he.net/man2/write)) in
 ---
 class: center, middle
 
 ---
 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.
 
 ???
 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.
 
 ???
 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
 
 ---
 class: center, middle
This page took 0.030767 seconds and 4 git commands to generate.