#!/usr/bin/python
from slides import Lecture, NumSlide, Slide, Bullet, SubBullet, PRE, URL


lecture = Lecture(
    "Twisted: The Framework Of Your Internet",
    NumSlide("What is Twisted?",
          Bullet("An event-driven networking framework"),
          Bullet("Implementations of common protocols"),
          Bullet("Support libraries for event-driven applications"),
          Bullet("Frameworks for specific types of network applications"),
    ),
    Slide("Metadata",
          Bullet("URL: ", URL("http://www.twistedmatrix.com")),
          Bullet("License: LGPL"),
          Bullet("Number of developers: approximately 17"),
          Bullet("Version: 0.18.0"), # don't forget to update before talk
          Bullet("Platforms: Unix, Win32, Jython"),
          Bullet("Started in January 2000, as a multiplayer game engine"),
    ),
    Slide("Why Twisted?",
          Bullet("Event driven model"),
          Bullet("APIs that scale:", SubBullet(
                 Bullet("Easy to learn"),
                 Bullet("More advanced capabilities for the expert"),
                 Bullet("Hide irrelevant implementation details"))),
          Bullet("Batteries included"),
          Bullet("Integration of multiple protocols and services"),
    ),
    Slide("Focus of this talk - twisted.internet",
          Bullet("Event driven networking package"),
          Bullet("Similar to asyncore, but better:", SubBullet(
                  Bullet("More features"),
                  Bullet("Cleaner design"))),
    ),
    Slide("Design patterns in twisted.internet",
          Bullet("Pattern-Oriented Software Architecture: Patterns for Concurrent and Networked Objects (POSA2)"),
          Bullet("Some papers online at: ", URL("http://www.cs.wustl.edu/~schmidt/ACE-papers.html")),
    ),
    Slide("Case Study -- Writing an echo server",
          Bullet("Read what client wrote, write it back"),
          Bullet("Comparison between asyncore and twisted"),
    ),
    Slide("Asyncore echo server",
          PRE("""\
class EchoChannel(asyncore.dispatcher):
    def __init__(self, sock):
        asyncore.dispatcher.__init__(self, sock)
        self.buffer = ""
    
    def handle_read(self):
       self.buffer += self.recv(8192)

    def handle_write(self):
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]

    def handle_close(self):
        self.close()

class EchoServer(asyncore.dispatcher):

    def __init__(self, addr):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.bind(addr)
        self.listen(5)
    
    def handle_accept (self):
        conn, addr = self.accept()
        EchoChannel(conn)
"""),
    ),
    Slide("Twisted echo server",
          PRE("""\
class Echo(protocol.Protocol):

    def dataReceived(self, data):
        self.transport.write(data)

class EchoFactory(protocol.ServerFactory):

    protocol = Echo
"""),
    ),
    Slide("Reactor objects",
          Bullet("Implementation of a networking event loop"),
          Bullet("Additional APIs related to event loop"),
          Bullet("Named after Reactor design pattern in POSA2"),
    ),
    Slide("What is an event loop?",
          Bullet("Single thread waiting for events"),
          Bullet("Take events and call methods based on events"),
          Bullet("Methods are called in same thread, and thus can't block"),
          Bullet("Example event types:", SubBullet(
                 Bullet("Socket readable --> read from socket and pass data to protocol"),
                 Bullet("Scheduled event --> call scheduled method"),)
          ),
    ),
    Slide("Transports and Protocols",
          Bullet("Reactors connect transports to protocols:", PRE("""\
from twisted.internet import reactor
reactor.listenTCP(8000, EchoFactory(), interface='127.0.0.1')
""")),
          Bullet("Example protocols: HTTP, SMTP, IRC"),
          Bullet("Transports supported by Twisted:",
                 SubBullet(Bullet("TCP"), Bullet("SSL"), Bullet("UDP"), Bullet("Unix sockets"), Bullet("Subprocess"))),
    ),
    Slide("Separation of Transport and Protocol",
          Bullet("Reuse protocols with different transports"),
          Bullet("Protocols are not dependent on event loop"),
          Bullet("Cleaner code"),
          Bullet("Interfaces not implementation specific"),
    ),
    Slide("Example of protocol/transport separation",
          Bullet("Write a protocol, say HTTP"),
          Bullet("The protocol now works with TCP"),
          Bullet("But it also works with SSL/TLS, without any changes"),
          Bullet("SSL support for protocol doesn't depend on SSL library implementation"),
    ),
    Slide("Another example",
          Bullet("Instant messaging client"),
          Bullet("We can use TCP - but what about firewalls?"),
          Bullet("Use SOCKSv4, SOCKSv5 and HTTP proxy CONNECT to circumvent firewall"),
          Bullet("Separation of transport from protocol makes this trivial"),
          Bullet("Protocol can work with various proxies without making any changes"),
    ),
    Slide("Connection-oriented Protocols",
          Bullet("TCP, SSL, Unix sockets"),
          Bullet("Get notified when a connection is made, and when it's lost"),
          Bullet("Receive data from transports"),
          Bullet("Write data to their transport, or register a producer that writes data"),
          Bullet("Close transport's connection"),
    ),
    Slide("Packet-oriented Protocols",
          Bullet("UDP"),
          Bullet("Receive packet from transport"),
          Bullet("Send packet to remote address"),
    ),
    Slide("Process Protocol",
          Bullet("For running subprocesses"),
          Bullet("Like connection-oriented protocols, but additional functionality"),
          Bullet("Get notified of data written to stderr"),
          Bullet("get notified of stderr and stdout closing"),
    ),
    Slide("Protocol factories",
          Bullet("Create protocol instances"),
          Bullet("Shared state for protocol instances"),
    ),
    Slide("Transport functionality",
          Bullet("Built-in buffering"),
          Bullet("Consumers for two types of producers:", SubBullet(
                 Bullet("Streaming - keep pushing data on their own"),
                 Bullet("Non-streaming - consumer tells producer when it runs out of data"))),
    ),
    NumSlide("Connection life cycle",
          Bullet("Protocol factory registered on TCP port"),
          Bullet("Remote client connects to port"),
          Bullet("Reactor creates new TCP transport connected to new socket"),
          Bullet("Reactor creates new protocol instance from factory"),
          Bullet("Transport is connected to protocol"),
          Bullet("Protocol can write and receives data from transport"),
          Bullet("Connection is lost and protocol is notified"),
    ),
    Slide("Reactor scheduling interfaces",
          Bullet("Schedule methods to be run in X seconds"),
          Bullet("Cancel scheduled method"),
          Bullet("Run methods in startup or shutdown of event loop"),
    ),
    Slide("Reactor threading interfaces",
          Bullet("Methods run by the event loop can't block"),
          Bullet("Most of the Twisted core is not thread-safe"),
          Bullet("Solution - threading integration in the reactor:", SubBullet(
                 Bullet("Run a method in a thread pool"),
                 Bullet("Allow other threads to schedule methods to be run in event loop thread"))),
          Bullet("Half-Sync/Half-Async design pattern"),
    ),
    Slide("Reactor implementations",
          Bullet("Twisted supports multiple reactors:", SubBullet( 
                 Bullet("select/poll"),
                 Bullet("Windows event API"),
                 Bullet("GUI toolkits"))),
          Bullet("Reactor can be chosen at runtime"),
    ),
    Slide("Reactor implementations - select/poll",
          Bullet("Runs on *nix and Win32"),
          Bullet("Same method as asyncore uses"),
          Bullet("Supports TCP, UDP, SSL"),
          Bullet("Process running, Unix sockets and stdin/out/err on *nix"),
    ),
    Slide("Reactor implementations - Win32's WaitForMultipleObjects",
       Bullet("Support TCP, UDP, SSL and process running"),
       Bullet("Should be easy to integrate with all win32 event APIs"),
       Bullet("Future support for win32 GUI"),
       Bullet("Limited to 64 events because of win32 API limitations"),
    ),  
    Slide("Reactor implementations - GTK+, Qt",
          Bullet("Runs on *nix and Win32"),
          Bullet("Use GUI event loop to drive networking event loop"),
          Bullet("Supports TCP, UDP, SSL"),
          Bullet("Unix sockets and process running on *nix"),
    ),
    Slide("Non-reactor GUI support",
          Bullet("Integrates with a reactor"),
          Bullet("GUI events get scheduled every few milliseconds"),
          Bullet("wxPython"),
          Bullet("Tkinter"),
    ),
    Slide("Java reactor for Jython",
          Bullet("TCP and possibly in the future SSL and UDP"),
          Bullet("Uses threads since Java pre-1.4 doesn't have event-driven networking APIs"),
    ),
    Slide("Reactor implementations - Win32 I/O Completion Ports",
          Bullet("Work in progress"),
          Bullet("Support TCP and process running"),      
          Bullet("Asynchronous I/O - uses Proactor design pattern"),
          Bullet("Only scalable I/O method for Windows"),
    ),
    Slide("Reactor implementations - future work",
          Bullet("C implementation of select()-based reactor"),
          Bullet("FreeBSD's kqueue, using pykqueue"),
          Bullet("POSIX asynchronous I/O"),
          Bullet("Other OS specific mechanisms, e.g. /dev/poll"),
          Bullet("Java 1.4's java.nio"),
    ),
    Slide("The future of twisted.internet",
           Bullet("The APIs are now stable, except:", SubBullet(
                  Bullet("UDP will be refactored"),
                  Bullet("Small backwards-compatible feature enhancements"))),
           Bullet("When these changes are done, switch to 0.99.x series"),
           Bullet("1.0 when completely documented and bug free"),
    ),              
    Slide("And now for something completely different",
          Bullet("Twisted has lots more to offer for developers"),
    ),
    Slide("Server deployment utilities",
          Bullet("twistd, application for running Twisted servers:", SubBullet(
                 Bullet("Log file location and automatic rotation"),
                 Bullet("Daemonization on *NIX systems"),
                 Bullet("Choose reactor at runtime"))
          ),
          Bullet("mktap: deploy preconfigured server setups as XML pickle"),
          Bullet("coil: edit taps using web interface"),
          Bullet("tap2deb: convert tap to Debian package, with /etc/init.d support"),
          Bullet("manhole: remote python shell for Twisted servers"),
    ),
    Slide("Protocol implementations -- twisted.protocols",
          Bullet("Utility classes for developing protocols, e.g. line-based ones"),
          Bullet("HTTP, SMTP, IRC, POP3, telnet, FTP, TOC, OSCAR, SOCKSv4, finger, DNS, NNTP, XML-RPC"),
          Bullet("LDAP support is available as separate package"),
    ),
    Slide("Database interface - twisted.enterprise",
          Bullet(".adbapi: Integrate blocking DB-API operations with event loop"),
          Bullet(".row: simplistic object/relational mapper"),
    ),
    Slide("Application frameworks",
          Bullet("twisted.mail: basic SMTP and POP3 maildrop and smarthost"),
          Bullet("twisted.names: DNS server framework"),
          Bullet("twisted.news: NNTP news server framework"),
          Bullet("twisted.web: web server with ZPublisher-like system"),
    ),
    Slide("Authorization interface -- twisted.cred",
          Bullet("Authorization and authentication backend"),
          Bullet("Basis for twisted.web sessions and PerspectiveBroker"),
          Bullet("Goal is to use as backend for all Twisted frameworks"),
    ),
    Slide("Perspective Broker - twisted.spread",
          Bullet("Capabilities based remote object protocol"),
          Bullet("Additional implementations in Java and Emacs"),
          Bullet("Goal: use this instead of inventing a new protocol"),
    ),
    Slide("A sample Twisted server - twisted.words",
          Bullet("words is an instant messaging and chat server"),
          Bullet("IRC protocol interface"),
          Bullet("Perpective Broker protocol interface"),
          Bullet("Web interface for signing up for new accounts"),
          Bullet("twisted.cred used to unify user authentication"),
          Bullet("All integrated into one server and process"),
    ),
    Slide("A sample Twisted client - t-im",
          Bullet("Multi-protocol instant messaging client using GTK+"),
          Bullet("Can connect to words server using Perspective Broker"),
          Bullet("IRC client"),
          Bullet("AIM client using TOC protocol"),
    ),
    Slide("twisted.internet again",
          Bullet("Clean design - separation of Protocol and Transport"),
          Bullet("Featureful API - scheduling, TCP/SSL/UDP, threading"),
          Bullet("Pluggable reactor objects drive event loop"),
          Bullet("Use Twisted now!"),
    ),
    Slide("Questions?",
          Bullet("Web: ", URL("http://www.twistedmatrix.com")),
          Bullet("IRC: #twisted on irc.openprojects.net"),
          Bullet("Mailing list: ", URL("http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python")),
    ),
)

lecture.renderHTML(".", "slide-%02d.html", css="main.css")
