spydurus.py :  » Web-Frameworks » Spyce » spyce-2.1 » contrib » modules » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Web Frameworks » Spyce 
Spyce » spyce 2.1 » contrib » modules » spydurus.py
# spydurus provides a threadsafe, pooled Spyce interface to a durus database.
# Author: Jonathan Ellis

# If you're just trying to get a feel for Spyce, the main thing to
# understand is that this provides (via a subclass) the get method you
# see used (e.g., "data.get(id)") in .spy pages.  More than that you don't
# really need to know unless you need to write your own connection
# pool module.

CONNECTIONS = 3 # max connections to put in the pool

import sys, os, os.path, threading, time
import spyce, spyceUtil

# try to start a server:
# in a production environment, you'd keep it running with inittab or something,
# so this step wouldn't be necessary.

# The best approach is to fork and then use StorageServer.serve to start durus;
# that way we don't have to worry about durus being on the path.  However,
# since win32 doesn't support fork, AND that's where we're most likely to have
# PATH issues (durus on win32 doesn't modify the path on install),
# in the interest of making this run out of the box for windows people we'll
# take the StorageServer approach, but in a thread, not a new process.

# Please use the inittab approach in production; Durus will be more performant
# in its own process.
from durus.storage_server import StorageServer
from durus.file_storage import FileStorage,TempFileStorage
_runningDurus = False
def maybeStartDurus(db_path):
    if spyce.getServer().threaded():
        _runningDurus = True
        def _maybeStartDurus():
            st = db_path and FileStorage(db_path) or TempFileStorage()
            try:
                StorageServer(st).serve()
            except:
                # already running
                _runningDurus = False
        _t = threading.Thread(target=_maybeStartDurus)
        _t.start()
        def _cleanup():
            if _runningDurus:
                from durus.run_durus import stop_durus,DEFAULT_HOST,DEFAULT_PORT
                stop_durus(DEFAULT_HOST, DEFAULT_PORT)
            _t.join()
        import atexit
        atexit.register(_cleanup)

import Queue
q = Queue.Queue()

def initPool(connections=3, db_path=None):
    "if another process takes care of durus, you never need to pass db_path"
    from durus.connection import Connection
    if spyce.getServer().threaded():
        from durus.client_storage import ClientStorage
        for i in range(connections * 3):
            if q.qsize() >= connections:
                break
            try:
                q.put(Connection(ClientStorage()))
            except:
                time.sleep(0.5) # sometimes takes a while for server to start
    else:
        # not a long-running process -- spyce running under [Fast]CGI or mod_python
        st = spyceUtil.tryForAwhile(lambda: FileStorage(db_path))
        if not st:
            raise 'timeout while getting durus connection'
        q.put(Connection(st))
    if not q.qsize():
        raise 'no durus connections created'

# the actual spyceModule is refreshingly short now that starting Durus is out of the way
from spyceModule import spyceModule

class spydurus(spyceModule):
    def start(self):
        self.conn = None
        try:
            self.conn = q.get(timeout=10)
        except Queue.Empty:
            raise 'timeout while getting durus connection'
        else:
            self.conn.abort() # syncs connection

    # spyce automatically calls finish methods at the end of each request.
    # this is an excellent way to make sure that our connection always
    # returns to the queue.
    def finish(self, err):
        q.put(self.conn)
        
    def root(self):
        return self.conn.get_root()

    def get(self, oid):
        """oid should be a formatted oid, not a raw _p_oid"""
        return self.conn.get(int(oid))

    def commit(self):
        self.conn.commit()

# you may wish to inherit from this instead of Persistent directly
from durus.persistent import Persistent
class PersistentWithId(Persistent):
    # _p_format_oid is rather cumbersome to type
    def id(self):
        return self._p_format_oid()
    
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.