[Twisted-Python] Bug in Finger Tutorial?
Hello, I am confused about how the FingerService gets started in the finger/finger.py makeService function. It is never assigned a service parent and it can't service getUser requests if its startService method isn't called; you get an AttributeError: "no attribute 'users'" the way it works now. Is this a bug? The most sensible thing, in this case, seems to be setting the FingerServiceparent to be the MultiService container that all of the interent services are added to in the makeService function. Is that correct? I'm wondering if their are any other strategies people use for starting non-internet services. For instance, if instead of reading a file to get to my user db, I might want to start a redis client and read from redis to service a getUser call. But that means I'd want to make sure the startService call succeeded (the redis connection was made) before one of the internet services tries to use the FingerService (a timing problem that doesn't exist when just reading a file)...or something. Maybe I'm really just wondering how the twisted application framework handles exceptions that occur for startService calls. Maybe I need something else to handle that kind of thing? I'm also wondering if it's ever a good idea to make a extension of ServerFactory (that adapts a Service) that calls Service.startService when Factory.startServer is called (and Service.stopService when Factory.stopFactory is called)? And I'm looking for more use cases/projects (beyond the finger tutorial) that really showcase the twisted application framework. Any references would be appreciated! Thanks! -Dorian
I'll take care of the first question.
From The Evolution of Finger: making a finger library,
h = internet.TCPServer(79, IFingerFactory(f))
notice IFingerFactory? If you read the earlier parts of the tutorial,
you'll see stuff like components.registerAdapter. It's just magic to
create a FingerFactoryFromService, giving its constructor f, the
"Finger Service". What happens here is that "f", the Finger Service,
is different from the service.Service within the Twisted Framework.
You might as well call "f", the Finger Service, "Finger Shared Data".
What really happens here is
h is the service that has parent s, MultiService. s is then returned
and started by the application.
h contains a factory that gets run.
The factory knows "f", the Finger Service, which has nothing to do
with twisted's mechanism. It's more of a demo for the component based
framework. f is a way to share data and methods and states across
multiple factories.
I am also very new to twisted, so I **hope** this understanding of
mine is correct ...
I strongly recommend you read through the entire tutorial. They build
very incrementally, so most of the time the code is repeated so you
can just skim through it if you had started from the beginning.
David Kao
On Fri, Sep 30, 2011 at 5:28 AM, Dorian Raymer
Hello, I am confused about how the FingerService gets started in the finger/finger.py makeService function. It is never assigned a service parent and it can't service getUser requests if its startService method isn't called; you get an AttributeError: "no attribute 'users'" the way it works now. Is this a bug? The most sensible thing, in this case, seems to be setting the FingerService parent to be the MultiService container that all of the interent services are added to in the makeService function. Is that correct? I'm wondering if their are any other strategies people use for starting non-internet services. For instance, if instead of reading a file to get to my user db, I might want to start a redis client and read from redis to service a getUser call. But that means I'd want to make sure the startService call succeeded (the redis connection was made) before one of the internet services tries to use the FingerService (a timing problem that doesn't exist when just reading a file)...or something. Maybe I'm really just wondering how the twisted application framework handles exceptions that occur for startService calls. Maybe I need something else to handle that kind of thing? I'm also wondering if it's ever a good idea to make a extension of ServerFactory (that adapts a Service) that calls Service.startService when Factory.startServer is called (and Service.stopService when Factory.stopFactory is called)? And I'm looking for more use cases/projects (beyond the finger tutorial) that really showcase the twisted application framework. Any references would be appreciated! Thanks! -Dorian _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
On Thu, Sep 29, 2011 at 2:44 PM, David Kao
I'll take care of the first question.
From The Evolution of Finger: making a finger library,
h = internet.TCPServer(79, IFingerFactory(f))
notice IFingerFactory? If you read the earlier parts of the tutorial, you'll see stuff like components.registerAdapter. It's just magic to create a FingerFactoryFromService, giving its constructor f, the "Finger Service". What happens here is that "f", the Finger Service, is different from the service.Service within the Twisted Framework.
The FingerService inherits service.Service and implements the startServiceevent, so it *is* a service that can be run by the service framework; it just isn't one of the twisted.application.internet services, like internet.TCPServer. Moreover, it needs to have startService called, somehow... and what I'm saying is that in the full example (provided in twisted/doc/core/howto/tutorial/listings/finger/finger/finger.py) it is not called, and if you actually try using it, it doesn't work. You might as well call "f", the Finger Service, "Finger Shared Data".
What really happens here is
h is the service that has parent s, MultiService. s is then returned and started by the application.
h contains a factory that gets run.
The factory knows "f", the Finger Service, which has nothing to do with twisted's mechanism. It's more of a demo for the component based framework. f is a way to share data and methods and states across multiple factories.
I am also very new to twisted, so I **hope** this understanding of mine is correct ...
I strongly recommend you read through the entire tutorial. They build very incrementally, so most of the time the code is repeated so you can just skim through it if you had started from the beginning.
I've read it many times over the years ;) It's surprisingly complete as an example...you just don't know that in the beginning. The topic area of this question is something I'm trying to squeeze out of this tutorial series; I'm encountering conceptual questions beyond the mechanics of how the framework works (which the tutorial does a great job of explaining) like: should I ever make a tree of dependent services? What if I do something in a startService method that I want to make sure works before other services get their startService called? If I create a bunch of business services (that just provide pure functionality) that I then adapt for deployment in different t.a.internet services, should I put the business services in their own MultiService and the internet services in their own MutiService container? Like I said, more showcasing of use cases would help suggest answers to these kind of questions. I see a lot of possibilities, but haven't put in the time in the trenches to try them all out ;) Thanks, -Dorian
David Kao
Hello, I am confused about how the FingerService gets started in the finger/finger.py makeService function. It is never assigned a service
On Fri, Sep 30, 2011 at 5:28 AM, Dorian Raymer
wrote: parent and it can't service getUser requests if its startService method isn't called; you get an AttributeError: "no attribute 'users'" the way it works now. Is this a bug? The most sensible thing, in this case, seems to be setting the FingerService parent to be the MultiService container that all of the interent services are added to in the makeService function. Is that correct? I'm wondering if their are any other strategies people use for starting non-internet services. For instance, if instead of reading a file to get to my user db, I might want to start a redis client and read from redis to service a getUser call. But that means I'd want to make sure the startService call succeeded (the redis connection was made) before one of the internet services tries to use the FingerService (a timing problem that doesn't exist when just reading a file)...or something. Maybe I'm really just wondering how the twisted application framework handles exceptions that occur for startService calls. Maybe I need something else to handle that kind of thing? I'm also wondering if it's ever a good idea to make a extension of ServerFactory (that adapts a Service) that calls Service.startService when Factory.startServer is called (and Service.stopService when Factory.stopFactory is called)? And I'm looking for more use cases/projects (beyond the finger tutorial) that really showcase the twisted application framework. Any references would be appreciated! Thanks! -Dorian _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
On Fri, Sep 30, 2011 at 6:10 AM, Dorian Raymer
On Thu, Sep 29, 2011 at 2:44 PM, David Kao
wrote: I'll take care of the first question.
From The Evolution of Finger: making a finger library,
h = internet.TCPServer(79, IFingerFactory(f))
notice IFingerFactory? If you read the earlier parts of the tutorial, you'll see stuff like components.registerAdapter. It's just magic to create a FingerFactoryFromService, giving its constructor f, the "Finger Service". What happens here is that "f", the Finger Service, is different from the service.Service within the Twisted Framework.
The FingerService inherits service.Service and implements the startService event, so it *is* a service that can be run by the service framework; it just isn't one of the twisted.application.internet services, like internet.TCPServer. Moreover, it needs to have startService called, somehow... and what I'm saying is that in the full example (provided in twisted/doc/core/howto/tutorial/listings/finger/finger/finger.py) it is not called, and if you actually try using it, it doesn't work.
Yes you are right. It's just the two concepts (adapter and service) are different but are presented together. In this case, it happens that FingerService needs initialization, and that initialization is usually done via startService, which, I agree, isn't called. And it's funky here because you don't want FingerService to be the service here, because it doesn't know how to listen to TCP. bahhh ... yea the example is not super great. It seems like you understand the examples anyways.
You might as well call "f", the Finger Service, "Finger Shared Data".
What really happens here is
h is the service that has parent s, MultiService. s is then returned and started by the application.
h contains a factory that gets run.
The factory knows "f", the Finger Service, which has nothing to do with twisted's mechanism. It's more of a demo for the component based framework. f is a way to share data and methods and states across multiple factories.
I am also very new to twisted, so I **hope** this understanding of mine is correct ...
I strongly recommend you read through the entire tutorial. They build very incrementally, so most of the time the code is repeated so you can just skim through it if you had started from the beginning.
I've read it many times over the years ;) It's surprisingly complete as an example...you just don't know that in the beginning. The topic area of this question is something I'm trying to squeeze out of this tutorial series; I'm encountering conceptual questions beyond the mechanics of how the framework works (which the tutorial does a great job of explaining) like: should I ever make a tree of dependent services? What if I do something in a startService method that I want to make sure works before other services get their startService called? If I create a bunch of business services (that just provide pure functionality) that I then adapt for deployment in different t.a.internet services, should I put the business services in their own MultiService and the internet services in their own MutiService container? Like I said, more showcasing of use cases would help suggest answers to these kind of questions. I see a lot of possibilities, but haven't put in the time in the trenches to try them all out ;) Thanks, -Dorian
Totally agree with your suggestion. I have the exact same problem here. In the end I just start doing things using reactor.listenTCP and forget about services since it isn't clear in the docs the order in which services are started. I sort of use one big setup service as "Main()", and then do my own hooks using "fake service" inside each factory, and the call reactor.listenTCP on those factories. It might just be services are meant to be really independent and parallel to each other. I dunno ... I'll let the veterans speak now.
David Kao
On Fri, Sep 30, 2011 at 5:28 AM, Dorian Raymer
wrote: Hello, I am confused about how the FingerService gets started in the finger/finger.py makeService function. It is never assigned a service parent and it can't service getUser requests if its startService method isn't called; you get an AttributeError: "no attribute 'users'" the way it works now. Is this a bug? The most sensible thing, in this case, seems to be setting the FingerService parent to be the MultiService container that all of the interent services are added to in the makeService function. Is that correct? I'm wondering if their are any other strategies people use for starting non-internet services. For instance, if instead of reading a file to get to my user db, I might want to start a redis client and read from redis to service a getUser call. But that means I'd want to make sure the startService call succeeded (the redis connection was made) before one of the internet services tries to use the FingerService (a timing problem that doesn't exist when just reading a file)...or something. Maybe I'm really just wondering how the twisted application framework handles exceptions that occur for startService calls. Maybe I need something else to handle that kind of thing? I'm also wondering if it's ever a good idea to make a extension of ServerFactory (that adapts a Service) that calls Service.startService when Factory.startServer is called (and Service.stopService when Factory.stopFactory is called)? And I'm looking for more use cases/projects (beyond the finger tutorial) that really showcase the twisted application framework. Any references would be appreciated! Thanks! -Dorian _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
On Thu, Sep 29, 2011 at 3:23 PM, David Kao
On Fri, Sep 30, 2011 at 6:10 AM, Dorian Raymer
wrote: On Thu, Sep 29, 2011 at 2:44 PM, David Kao
wrote: I'll take care of the first question.
From The Evolution of Finger: making a finger library,
h = internet.TCPServer(79, IFingerFactory(f))
notice IFingerFactory? If you read the earlier parts of the tutorial, you'll see stuff like components.registerAdapter. It's just magic to create a FingerFactoryFromService, giving its constructor f, the "Finger Service". What happens here is that "f", the Finger Service, is different from the service.Service within the Twisted Framework.
The FingerService inherits service.Service and implements the
startService
event, so it *is* a service that can be run by the service framework; it just isn't one of the twisted.application.internet services, like internet.TCPServer. Moreover, it needs to have startService called, somehow... and what I'm saying is that in the full example (provided in twisted/doc/core/howto/tutorial/listings/finger/finger/finger.py) it is not called, and if you actually try using it, it doesn't work.
Yes you are right. It's just the two concepts (adapter and service) are different but are presented together. In this case, it happens that FingerService needs initialization, and that initialization is usually done via startService, which, I agree, isn't called. And it's funky here because you don't want FingerService to be the service here, because it doesn't know how to listen to TCP. bahhh ... yea the example is not super great. It seems like you understand the examples anyways.
You might as well call "f", the Finger Service, "Finger Shared Data".
What really happens here is
h is the service that has parent s, MultiService. s is then returned and started by the application.
h contains a factory that gets run.
The factory knows "f", the Finger Service, which has nothing to do with twisted's mechanism. It's more of a demo for the component based framework. f is a way to share data and methods and states across multiple factories.
I am also very new to twisted, so I **hope** this understanding of mine is correct ...
I strongly recommend you read through the entire tutorial. They build very incrementally, so most of the time the code is repeated so you can just skim through it if you had started from the beginning.
I've read it many times over the years ;) It's surprisingly complete as an example...you just don't know that in the beginning. The topic area of this question is something I'm trying to squeeze out of this tutorial series; I'm encountering conceptual questions beyond the mechanics of how the framework works (which the tutorial does a great job of explaining) like: should I ever make a tree of dependent services? What if I do something in a startService method that I want to make sure works before other services get their startService called? If I create a bunch of business services (that just provide pure functionality) that I then adapt for deployment in different t.a.internet services, should I put the business services in their own MultiService and the internet services in their own MutiService container? Like I said, more showcasing of use cases would help suggest answers to these kind of questions. I see a lot of possibilities, but haven't put in the time in the trenches to try them all out ;) Thanks, -Dorian
Totally agree with your suggestion.
I have the exact same problem here. In the end I just start doing things using reactor.listenTCP and forget about services since it isn't clear in the docs the order in which services are started. I sort of use one big setup service as "Main()", and then do my own hooks using "fake service" inside each factory, and the call reactor.listenTCP on those factories.
Cool, yeah I do similar things as well.
It might just be services are meant to be really independent and parallel to each other. I dunno ... I'll let the veterans speak now.
Yeah, there is definitely a lot of value in keeping the transport enabling services separate from the functional services. Keeping them independent and parallel seems like the better way to go. Maybe my misunderstanding is what the scope of Twisted Services was intended to be...Up to now, I've been thinking about designing applications that use Twisted Services for both pure business functionality AND for things that provide network transport. I briefly looked at how erlang/OTP handles starting dependencies in apps. The rabbitmq app blocks/waits for each major component to start (which would be like a Twisted Service.startService returning a Deferred). I guess this is just a hard problem, or maybe I'm missing a concept.
Thanks, -Dorian
David Kao
On Fri, Sep 30, 2011 at 5:28 AM, Dorian Raymer
wrote:
Hello, I am confused about how the FingerService gets started in the finger/finger.py makeService function. It is never assigned a service parent and it can't service getUser requests if its startService method isn't called; you get an AttributeError: "no attribute 'users'" the way it works now. Is this a bug? The most sensible thing, in this case, seems to be setting the FingerService parent to be the MultiService container that all of the interent services are added to in the makeService function. Is that correct? I'm wondering if their are any other strategies people use for starting non-internet services. For instance, if instead of reading a file to get to my user db, I might want to start a redis client and read from redis to service a getUser call. But that means I'd want to make sure the startService call succeeded (the redis connection was made) before one of the internet services tries to use the FingerService (a timing problem that doesn't exist when just reading a file)...or something. Maybe I'm really just wondering how the twisted application framework handles exceptions that occur for startService calls. Maybe I need something else to handle that kind of thing? I'm also wondering if it's ever a good idea to make a extension of ServerFactory (that adapts a Service) that calls Service.startService when Factory.startServer is called (and Service.stopService when Factory.stopFactory is called)? And I'm looking for more use cases/projects (beyond the finger tutorial) that really showcase the twisted application framework. Any references would be appreciated! Thanks! -Dorian _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
participants (2)
-
David Kao
-
Dorian Raymer