Anonymous avatar Anonymous committed 4da6159

First implementation of exposing actors over wsgi.

Comments (0)

Files changed (2)

     spawn = classmethod(spawn)
     spawn_link = classmethod(spawn_link)
 
+    all_actors = {}
+
     def __init__(self, run=None):
         api.Greenlet.__init__(self, parent=api.get_hub().greenlet)
 
         else:
             self._to_run = lambda *args, **kw: run(self.receive, *args, **kw)
 
+        self.actor_id = str(uuid.uuid1())
+        self.all_actors[self.actor_id] = self
+
     #######
     ## Methods for general use
     #######
 
+    def rename(self, name):
+        """Change this actor's public name on this server.
+        """
+        del self.all_actors[self.actor_id]
+        self.actor_id = name
+        self.all_actors[name] = self
+
     def receive(self, *patterns):
         """Select a message out of this Actor's mailbox. If patterns
         are given, only select messages which match these shapes.
         """
         raise NotImplementedError("Implement in subclass.")
 
+    def cooperate(self):
+        self.sleep(0)
+
+    def sleep(self, amount):
+        api.sleep(amount)
+
     #######
     ## Implementation details
     #######
             self._exit_event.send_exception(*exc_info)
         for link in self._exit_links:
             link.cast({'address': self.address, 'exit': result})
+        self.all_actors.pop(self.actor_id)
 
     def _cast(self, message):
         """For internal use.
+
+import traceback
+import simplejson
+
+from pyact import actor
+
+
+def spawn_code(code_string):
+    EvalActor.spawn(None, code_string)
+
+
+class EvalActor(actor.Actor):
+    def main(self, path, body):
+        if path is not None:
+            self.rename(path)
+        try:
+            exec body in {
+                'actor_id': self.actor_id,
+                'receive': self.receive,
+                'cooperate': self.cooperate,
+                'sleep': self.sleep,
+                'spawn_code': spawn_code}
+        except:
+            traceback.print_exc()
+
+
+class ActorApplication(object):
+    def __call__(self, env, start_response):
+        path = env['PATH_INFO'][1:]
+        method = env['REQUEST_METHOD']
+        if method == 'PUT':
+            if not path:
+                start_response('405 Method Not Allowed', [('Content-type', 'text/plain')])
+                return 'Method Not Allowed\n'
+            new_actor = EvalActor.spawn(path, env['wsgi.input'].read(int(env['CONTENT_LENGTH'])))
+            start_response('202 Accepted', [('Content-type', 'text/plain')])
+            return 'Accepted\n'
+        elif method == 'POST':
+            old_actor = actor.Actor.all_actors.get(path)
+            if old_actor is None:
+                start_response('404 Not Found', [('Content-type', 'text/plain')])
+                return "Not Found\n"
+            try:
+                body = env['wsgi.input'].read(int(env['CONTENT_LENGTH']))
+                msg = simplejson.loads(body)
+            except Exception, e:
+                traceback.print_exc()
+                start_response('406 Not Acceptable', [('Content-type', 'text/plain')])
+                return 'Not Acceptable\n'
+            old_actor.address.cast(msg)
+            start_response('202 Accepted', [('Content-type', 'text/plain')])
+            return 'Accepted\n'            
+        elif method == 'DELETE':
+            old_actor = actor.Actor.all_actors.get(path)
+            if old_actor is None:
+                start_response('404 Not Found', [('Content-type', 'text/plain')])
+                return "Not Found\n"
+            old_actor.address.kill()
+            start_response('200 OK', [('Content-type', 'text/plain')])
+            return '\n'
+        elif method == 'GET':
+            if not path:
+                start_response('200 OK', [('Content-type', 'text/plain')])
+                return 'index\n'
+            elif path == 'some-js-file.js':
+                start_response('200 OK', [('Content-type', 'text/plain')])
+                return 'some-js-file\n'            
+            old_actor = actor.Actor.all_actors.get(path)
+            if old_actor is None:
+                start_response('404 Not Found', [('Content-type', 'text/plain')])
+                return "Not Found\n"
+            start_response('200 OK', [('Content-type', 'text/plain')])
+            return str(old_actor)
+
+
+app = ActorApplication()
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.