Understanding basics and Program Design

87 views
Skip to first unread message

Think Kos

unread,
Aug 31, 2014, 7:39:33 AM8/31/14
to python...@googlegroups.com
Hello,

I've been playing with Pulsar for a while, but still don't really understand how I can create an application.
The basic things I've written were first based on examples.snippets.greeter, now I'm using worker_start, as in pulsar.apps.socket. But still, I don't even understand how to properly stop the app.
I feel like the tutorials should be more explanatory. Maybe it's because I'm new to actor thing, but the docs don't help me that much, you're my only hope.

Let's get specific.
I want to write a tool that wraps a third party process using Popen, and fires events based on it (start, stop, output, etc.). Other parts of my tool will bind to those events. Those parts would be self contained, think of them as extensions to the core.

Here's something that's similar to what I want to achieve:
from pulsar import Application, MultiApp, EventHandler, new_event_loop


class EventProxy(EventHandler):
    MANY_TIMES_EVENTS = ['test']


# I think this shouldn't be a MultiApp, but this way I can create a Wrapper easily.
# How else can this be done?
class Core(MultiApp):
    def build(self):
        p = EventProxy()
        yield self.new_app(Wrapper, event_proxy=p)
        ExtensionA(p)
        ExtensionB(p)


class Wrapper(Application):
    def worker_start(self, worker, exc=None):
        # Why can't this be in build as EventProxy(loop=...)?
        self.cfg.event_proxy._loop = new_event_loop()
        self._loop = worker._loop
        self._loop.call_later(1, self.test)

    def test(self):
        for i in range(3):
            self.cfg.event_proxy.fire_event('test', i)

        # How do I exit the program?


class ExtensionA:
    def __init__(self, event_proxy):
        event_proxy.bind_event('test', self.handle_test)

    def handle_test(self, i):
        print('A:', i)


class ExtensionB:
    def __init__(self, event_proxy):
        event_proxy.bind_event('test', self.handle_test)

    def handle_test(self, i):
        print('B:', i)


if __name__ == '__main__':
    Core().start()

I have the feeling everything I did is wrong. Should I even be mixing Apps and Events? What's the best way to do all of this?

lsbardel

unread,
Sep 12, 2014, 4:11:21 AM9/12/14
to python...@googlegroups.com

On Sunday, August 31, 2014 12:39:33 PM UTC+1, Think Kos wrote:
Hello,

Hi, sorry for late reply, been away.


I've been playing with Pulsar for a while, but still don't really understand how I can create an application.
The basic things I've written were first based on examples.snippets.greeter, now I'm using worker_start, as in pulsar.apps.socket. But still, I don't even understand how to properly stop the app.
I feel like the tutorials should be more explanatory. Maybe it's because I'm new to actor thing, but the docs don't help me that much, you're my only hope.

You are right, the application framework doesn't have any overview on how to write an app. The overview should be here
but no contents yet. There are docs for the API here
but a tutorial page should also be available.
Maybe you can add an issue on github?


Let's get specific.
I want to write a tool that wraps a third party process using Popen, and fires events based on it (start, stop, output, etc.). Other parts of my tool will bind to those events. Those parts would be self contained, think of them as extensions to the core.
 
Why are you using a MultiApp when you have only one Application?

The ``worker_start`` method of the Application class is called every time an actor start running the application. It is where you do the Application initialisation.

When you initialise an Application you can pass as first positional argument a ``callable`` (the tool wrapping the third party process in your case)
which you can access in the ``worker_start`` method via ``self.cfg.callable``.

Callable is not the best name for it really, a better name should be ``handle`` or something like that.


I have the feeling everything I did is wrong. Should I even be mixing Apps and Events? What's the best way to do all of this?

Why are you creating a new event loop? Don't do that unless you are writing blocking code. Check this for example

EventHandler is just a tool for coordinating callbacks in an event loop. The Application class is a framework for writing servers which use multithreading or multiprocess, mixing them is not an issue. However your callable should not derive from the EventHandler if you are initializing it before the application starts.

class MyApp(Application):
   def worker_start(self, worker, exc=None):
       self._loop.call_later(1, self.test, worker)

    def test(self, worker):
       for i in range(3):
           
self.cfg.callable.handle_test(i)

       # How do I exit the program?

       worker
.stop()


class ThirdParty:

    def handle_test(self, i):
       ...


if __name__ == '__main__':
   MyApp(ThirdParty()).start()


Reply all
Reply to author
Forward
0 new messages