Example files in this directory are meant to illustrate features of asyncoro
framework. They are not necessarily efficient versions, nor very useful. The
descriptions below are sorted on the names of files, so some examples at the
beginning use advanced features, whereas later files (especially files that
start with 'tut_') may be easier to follow. In some cases, 'encode' method is
called on strings so same code works with Python 2 (where 'encode' returns
string itself) and Python 3 (where 'encode' returns bytes as needed). When
programming with Python 2 exclusively, there is no need to call 'encode'.

dispy project (http://dispy.sourceforge.net) uses asyncoro to implement Python
framework for distributed and parallel computing.

* chat_chan_client.py and chat_chan_server.py use broadcasting over a channel to
  send messages to all participants to implement a simple chat (message)
  service.  To use this and other 'chat' examples below, run the server, and
  multiple clients (either on same machine or other machines in local
  network). Messages typed in one client show up at other clients.

* chat_sock_client.py and chat_sock_server.py use asynchronous network
  programming, coroutines and message passing to implement a chat (message)
  server that is used by clients to broadcast messages.

* discoro_client1.py illustrates how to use discoro to distribute computations
  to remote servers to run them as coroutines on those servers and get results
  back to client.

* discoro_client2.py is a variation of discoro_client1.py. In this example,
  http server is used to monitor cluster, nodes, remote coroutines.

* discoro_client3.py shows how to exchange messages with objects (instances of
  class) between client and remote coroutines.

* discoro_client4.py sends files at the client to remote process to execute
  computations that process those files and the remote process in turn sends the
  results in files back to the client.

* discoro_client5.py runs an external program (discoro_client5_proc.py) at
  remote servers. The program reads from standard input and writes to standard
  output. Asynchronous pipes and message passing are used to send input from
  client to this program executing on remote servers, and get the output back to
  client.

* discoro_client6.py uses streaming of data to remote coroutines for efficient
  communication. The example also shows how to implement live/real-time
  analytics and send them to client.

* discoro_client6_channel.py is same as discoro_client6.py, except it uses
  channel to broadcast data to remote coroutines.

* discoro_client7.py is an alternate implementation of discoro_client1.py; it
  uses messages from discoro scheduler to schedule remote coroutines and get
  results.

* discoro_client8.py demonstrates that long-runnning computations without
  'yield' often can be executed. In this case, 'time.sleep' is used to simulate
  computation. Note that 'time.sleep' blocks entire asyncoro framework, so no
  other coroutines can execute until next 'yield'. With version 4.1 (and above),
  I/O processing, message passing, sending heartbeat messages to scheduler
  etc. are handled by a separate (called "reactive") asyncoro scheduler that is
  not affected by user's coroutines. So messages sent by client are received and
  queued by reactive scheduler.

* discoro_client9_node.py uses status messages from discoro scheduler to
  distribute data files to nodes and run node specific setup coroutine to load
  the data in memory. This data is then processed in computations to illustrate
  in-memory processing. This example doesn't work with Windows (due to lack of
  'fork' in Windows), so nodes running Windows are filtered out using
  DiscoroNodeAllocate.

* discoro_client9_server.py is similar to discoro_client9_node.py above, except
  that instead of initializing (memory in) nodes, each server in each node is
  initialized by distributing one file per server (note that one node may run as
  many servers as there are processors on that node), which is then read in
  memory on that server for in-memory processing at server level.

* discoro_httpd1.py shows how to use httpd module to provide HTTP interface to
  monitor discoro cluster.

* discoro_httpd2.py is a variant of discoro_httpd1.py to use 'status_coro' to
  process messages from discoro scheduler (in this case just to print when a
  remote coroutine is finished) while also using httpd module (which chains
  messages from discoro scheduler to client's 'status_proc').

* discoro_ssh_ec2.py shows how to use ssh port forwarding to work with Amazon
  EC2 cloud computing. In this example client runs locally and discoronode runs
  on remote Amazon EC2 cloud infrastructure.

* hotswap.py and hotswap_funcs.py illustrate how a running coroutine function
  can be swapped with a new function. The currently running function
  checks/validates the function being replaced, any unprocessed messages in the
  coroutine are processed with new functionality.

* pipe_csum.py uses asynchronous pipes to write data to and read data from a
  system program (that computes checksum of data).

* pipe_grep.py uses chained pipes with asynchronous read and write interface to
  count number of lines matching a pattern.

* rci_monitor_client.py and rci_monitor_server.py illustrate another approach to
  execute remote coroutines: The server registers a function and client requests
  to execute coroutine with that function. Compare this to discoro_client.py
  where the client sends the computation itself to the remote server, so the
  client can execute arbitrary functions, whereas with RCI only registered
  functions can be executed by clients.

* remote_channel_client.py and remote_channel_server.py use broadcasting
  channels to exchange messages among a sender and local/remote recipients.

* remote_coro_client.py and remote_coro_server.py exchange messages with
  one-to-one message passing to exchange messages between two remote coroutines.

* socket_afile.py creates a server and a client connected with a socket, which
  is then converted to asynchronous file. The server and client exchange data
  with asynchronous file interface. This example doesn't work in Windows, as
  sockets in Windows don't have underlying file.

* tut_channel.py is another example illustrating usage of broadcasting channel
  to exchange messages in local coroutines.

* tut_client.py and tut_server.py show message passing between remote client and
  server coroutines.

* tut_client_server.py shows message passing between local client and server
  coroutines. The remote version and local version are similar, except that
  remote versions register/locate coroutines.

* tut_coros.py creates a number of coroutines that each suspend execution for a
  brief period. The number of coroutines created can be increased to thousands
  or tens of thousands to show asyncoro can scale well.

* tut_sock_client.py and tut_sock_server.py use asynchronous network
  programmming to communicate.

* udp.py creates client server coroutines that communicate using asynchronous
  UDP sockets.

* webserver.py is an impelementation of "Ping Pong" benchmark server described
  at http://nichol.as/asynchronous-servers-in-python.
