Skip to content

Commit

Permalink
little bit more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
progrium committed Apr 28, 2012
1 parent 07bc480 commit e667387
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 29 deletions.
51 changes: 22 additions & 29 deletions docs/index.rst
Expand Up @@ -5,48 +5,41 @@ Ginkgo is a lightweight framework for writing network service daemons in
Python. It currently focuses on gevent as its core networking and concurrency
layer.

Here's what writing a simple server application looks like:
The core idea behind Ginkgo is the "service model", where your primary building
block or component of applications are composable services. A service is a
mostly self-contained module of your application that can start/stop/reload,
contain other services, manage async operations, and expose configuration.

::

import random
from ginkgo import Service, Setting
from ginkgo.async.gevent import ServerWrapper

class NumberServer(Service):
"""TCP server that emits random numbers"""

address = Setting("numbers.bind", default=('0.0.0.0', 7776))
emit_rate = Setting("numbers.rate_per_min", default=60)
class ExampleService(Service):
setting = Setting("example.setting", default="Foobar")

def __init__(self):
self.add_service(ServerWrapper(
StreamServer(self.address, self.handle)))
logging.info("Service is initializing.")

self.subservice = AnotherService(self.setting)
self.add_service(self.subservice)

def handle(self, socket, address):
while True:
try:
number = random.randint(0, 10)
socket.send("{}\n".format(number))
self.async.sleep(60 / self.emit_rate)
except IOError:
break # Connection lost
def do_start(self):
logging.info("Service is starting.")

With this module you now have a configurable, daemonizable server ready to be
deployed. Ginkgo gives you a simple runner to execute your app:
self.spawn(self.something_async)

$ ginkgo server.NumberServer
def do_stop(self):
logging.info("Service is stopping.")

As well as a more full featured service management tool:
def do_reload(self):
logging.info("Service is reloading.")

$ ginkgoctl server.NumberServer start
# ...

Check out the Quickstart to see how you can reload this service and see it
apply configuration changes without stopping!
Around this little bit of structure and convention, Ginkgo provides just a few
baseline features to make building both complex and simple network daemons much
easier.

Features
========
- Service primitive for composing large (or small) apps from simple components
- Service class primitive for composing daemon apps from simple components
- Dynamic configuration loaded from regular Python source files
- Runner and service manager tool for easy, consistent usage and deployment
- Integrated support for standard Python logging
Expand Down
27 changes: 27 additions & 0 deletions docs/user/install.rst
@@ -0,0 +1,27 @@
Installation
============

Ginkgo is currently only available via GitHub, as it won't be released on PyPI
until it reaches a stable 1.0 release.

Get the Code
------------
You can either clone the public repository:

::
$ git clone git://github.com/progrium/ginkgo.git

Download the tarball:

::
$ curl -OL https://github.com/progrium/ginkgo/tarball/master

Or, download the zipball:

::
$ curl -OL https://github.com/progrium/ginkgo/zipball/master

Once you have a copy of the source, you can embed it in your Python package, or install it into your site-packages easily:

::
$ python setup.py install
37 changes: 37 additions & 0 deletions docs/user/intro.rst
@@ -0,0 +1,37 @@
Introduction
============

Origin
------
Ginkgo evolved from a project called "gevent_tools" that started as a
collection of common features needed when building gevent applications. The
author had previously made a habit of building lots of interesting little
servers as a hobby, and then at work found himself writing and dealing with
lots more given the company's service oriented architecture. Accustomed to using
the application framework in Twisted, when he finally saw the light and
discovered gevent, there was no such framework for that paradigm.

Dealing with so many projects, it was not practical to reinvent the same basic
features and architecture over and over again. The same way web frameworks made
it easy to "throw together" a web application, there needed to be a way to
quickly "throw together" network daemons. Not just simple one-off servers, but
large-scale, complex applications -- often part of a larger distributed system.

Through the experience of building large systems, a pattern emerged that was
like a looser, more object-oriented version of the actor model based around the
idea of services. This became the main feature of gevent_tools and it was later
renamed gservice. However, with the hope of supporting other async mechanisms
other than gevent's green threads (such as actual threads or processes, or
other similar network libraries), the project was renamed Ginkgo.

Vision
------
The Ginkgo microframework is a minimalist foundation for building very large
systems, beyond individual daemons. There were originally plans for
gevent_tools to include higher-level modules to aid in developing distributed
applications, such as service discovery and messaging primitives.

While Ginkgo will remain focused on "baseline" features common to pretty much
all network daemons, a supplementary project to act as a "standard library" for
Ginkgo applications is planned. Together with Ginkgo, the vision would be to
quickly "throw together" distributed systems from simple primitives.
43 changes: 43 additions & 0 deletions docs/user/quickstart.rst
@@ -0,0 +1,43 @@
Here's what writing a simple server application looks like:

::

# server.py

import random

from gevent.server import StreamServer

from ginkgo import Service, Setting
from ginkgo.async.gevent import ServerWrapper

class NumberServer(Service):
"""TCP server that emits random numbers"""

address = Setting("numbers.bind", default=('0.0.0.0', 7776))
emit_rate = Setting("numbers.rate_per_min", default=60)

def __init__(self):
self.add_service(ServerWrapper(
StreamServer(self.address, self.handle)))

def handle(self, socket, address):
while True:
try:
number = random.randint(0, 10)
socket.send("{}\n".format(number))
self.async.sleep(60 / self.emit_rate)
except IOError:
break # Connection lost

With this module you now have a configurable, daemonizable server ready to be
deployed. Ginkgo gives you a simple runner to execute your app:

::
$ ginkgo server.NumberServer

As well as a more full featured service management tool:

::
$ ginkgoctl server.NumberServer start

0 comments on commit e667387

Please sign in to comment.