0rpc / zerorpc-python

zerorpc for python
http://www.zerorpc.io
Other
3.17k stars 378 forks source link

problem with 3rd example on dotcloud.com #79

Closed schaefer0 closed 9 years ago

schaefer0 commented 10 years ago

this is the example where the server defines an exception class and the client calls the exception.

running ubuntu, client blows up with this error:

An error occurred: Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/zerorpc-0.4.4-py2.7.egg/zerorpc/core.py", line 148, in _async_task functor.pattern.process_call(self._context, bufchan, event, functor) File "/usr/local/lib/python2.7/dist-packages/zerorpc-0.4.4-py2.7.egg/zerorpc/patterns.py", line 30, in process_call result = functor(req_event.args) File "/usr/local/lib/python2.7/dist-packages/zerorpc-0.4.4-py2.7.egg/zerorpc/decorators.py", line 44, in call return self._functor(_args, _kargs) File "zerorpc_server3.py", line 5, in bad raise Exception(":P") Exception: :P

the server reports the error below, but does not blow up:

No handlers could be found for logger "zerorpc.core"

jpetazzo commented 10 years ago

Okay, the server isn't expected to blow up; it should catch the exception, report it, and keep going.

It gets the "keep going" part right; but it doesn't report the exception.

That's because at some point, the code switched to use the regular Python logging framework; and if that framework isn't properly configured, it doesn't output anything.

If you add those two lines in the beginning of the server code, it will work correctly:

import logging
logging.basicConfig()

I don't know if there is an easy way to figure out if logging was properly configured (and fallback to regular error reporting otherwise). Do we want that? I.e., do we want to display exceptions server-side if logging wasn't configured?

schaefer0 commented 10 years ago

HI, Jerome,

I am just a beginning user of zerorpc- I have a fairly complex application (its a program that writes a distributable program executes RPC's to handlers that makes the handlers "hot swappable" when the application is in "idle" mode) that uses an open source and unsupported version of jsonRPC and was considering switching to zerorpc because I use zeromq for messaging. I like the heartbeat timeouts in zerorpc, my jsonrpc doesn't have that and I have to tweak timeout durations.

I made the change you suggested and the server reaction changed (but I dont' know if this is better or worse) - Is this supposed to happen - is this part of the reporting process?

ERROR:zerorpc.core: Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/zerorpc-0.4.4-py2.7.egg/zerorpc/core.py", line 148, in _async_task functor.pattern.process_call(self._context, bufchan, event, functor) File "/usr/local/lib/python2.7/dist-packages/zerorpc-0.4.4-py2.7.egg/zerorpc/patterns.py", line 30, in process_call result = functor(req_event.args) File "/usr/local/lib/python2.7/dist-packages/zerorpc-0.4.4-py2.7.egg/zerorpc/decorators.py", line 44, in call return self._functor(_args, _kargs) File "zerorpc_server3.py", line 7, in bad raise Exception(":P") Exception: :P

I think generating exceptions serverside (if logging is not properly configured)would be useful. Because with complex programs (especially when debugging something new, or newly placed on a system) anything can go wrong at any time, More info is better than less (until all the "usual" bugs are worked out - and then only report priority faults)

thanks, bob s.

On Nov 22, 2013, at 2:30 PM, Jérôme Petazzoni wrote:

Okay, the server isn't expected to blow up; it should catch the exception, report it, and keep going.

It gets the "keep going" part right; but it doesn't report the exception.

That's because at some point, the code switched to use the regular Python logging framework; and if that framework isn't properly configured, it doesn't output anything.

If you add those two lines in the beginning of the server code, it will work correctly:

import logging logging.basicConfig() I don't know if there is an easy way to figure out if logging was properly configured (and fallback to regular error reporting otherwise). Do we want that? I.e., do we want to display exceptions server-side if logging wasn't configured?

— Reply to this email directly or view it on GitHub.

!DSPAM:528fb2df2424515744860!


robert schaefer Atmospheric Sciences Group MIT Haystack Observatory Westford, MA 01886

email: rps@haystack.mit.edu voice: 781-981-5767 www: http://www.haystack.mit.edu

jpetazzo commented 10 years ago

The behavior that you see is the expected one :-) Let me explain the rationale behind this...

When you run a ZeroRPC service, it is exposing a Python module (or a Python class instance, or even just a bunch of functions; it doesn't matter). You can then call those functions remotely, with a ZeroRPC client. So far, so good.

Now, what happens when there is an exception in the service code? We had (at least!) two options.

  1. Let the exception "bubble up", until it crashes the service. Pros: errors can't remain unnoticed (since they bring down the whole service). Cons: any kind of exception will crash the service, possibly interrupting in-flight requests.
  2. Catch the exception in the request handler, report it to the caller, and continue. Pros: the caller knows that an exception happened, but other requests are not affected. Cons: if the request changes some internal state, then the state might be undefined (because the request might be half-completed).

We decided to go for option 2. If you prefer option 1, maybe it could be implemented with an extra options. What do you think?

schaefer0 commented 10 years ago

Option 2 is good for me. thanks.

On Nov 29, 2013, at 5:32 PM, Jérôme Petazzoni wrote:

The behavior that you see is the expected one :-) Let me explain the rationale behind this...

When you run a ZeroRPC service, it is exposing a Python module (or a Python class instance, or even just a bunch of functions; it doesn't matter). You can then call those functions remotely, with a ZeroRPC client. So far, so good.

Now, what happens when there is an exception in the service code? We had (at least!) two options.

Let the exception "bubble up", until it crashes the service. Pros: errors can't remain unnoticed (since they bring down the whole service). Cons: any kind of exception will crash the service, possibly interrupting in-flight requests.

Catch the exception in the request handler, report it to the caller, and continue. Pros: the caller knows that an exception happened, but other requests are not affected. Cons: if the request changes some internal state, then the state might be undefined (because the request might be half-completed).

We decided to go for option 2. If you prefer option 1, maybe it could be implemented with an extra options. What do you think?

— Reply to this email directly or view it on GitHub.

!DSPAM:52991a902052492464979!


robert schaefer Atmospheric Sciences Group MIT Haystack Observatory Westford, MA 01886

email: rps@haystack.mit.edu voice: 781-981-5767 www: http://www.haystack.mit.edu

jpetazzo commented 10 years ago

OK. I think we just need to update examples to mention that one should enable logging to see exceptions on the server side :-)

schaefer0 commented 10 years ago

I was going to say that but I've found many open source maintainers to be a bit touchy when I make suggestions :-)

thanks!

On Dec 2, 2013, at 1:24 PM, Jérôme Petazzoni wrote:

OK. I think we just need to update examples to mention that one should enable logging to see exceptions on the server side :-)

— Reply to this email directly or view it on GitHub.

!DSPAM:529cd07e143093130430811!


robert schaefer Atmospheric Sciences Group MIT Haystack Observatory Westford, MA 01886

email: rps@haystack.mit.edu voice: 781-981-5767 www: http://www.haystack.mit.edu

jpetazzo commented 10 years ago

Suggestions always welcome! The tricky part is rather "when will we find some time to do this?" :-)

schaefer0 commented 10 years ago

Hi Jerome,

If you can still remember this thread - back in November I was trying to figure out what was going on with exceptions raised in the zerorpc server.

Your suggestion was to do this:

import logging logging.basicConfig()

This works fine but the information on exception goes to the terminal and I would like it to go to a file. I've developed a custom logger based on python's logger. My suggestion for zerorpc is to allow the passing in of a logger object to write to .log.error("error text") in initialization, default = None, and if None then use basicConfig

what do you think?

bob s.

On Nov 29, 2013, at 5:32 PM, Jérôme Petazzoni wrote:

The behavior that you see is the expected one :-) Let me explain the rationale behind this...

When you run a ZeroRPC service, it is exposing a Python module (or a Python class instance, or even just a bunch of functions; it doesn't matter). You can then call those functions remotely, with a ZeroRPC client. So far, so good.

Now, what happens when there is an exception in the service code? We had (at least!) two options.

Let the exception "bubble up", until it crashes the service. Pros: errors can't remain unnoticed (since they bring down the whole service). Cons: any kind of exception will crash the service, possibly interrupting in-flight requests.

Catch the exception in the request handler, report it to the caller, and continue. Pros: the caller knows that an exception happened, but other requests are not affected. Cons: if the request changes some internal state, then the state might be undefined (because the request might be half-completed).

We decided to go for option 2. If you prefer option 1, maybe it could be implemented with an extra options. What do you think?

— Reply to this email directly or view it on GitHub.

!DSPAM:52991a902052492464979!


robert schaefer Atmospheric Sciences Group MIT Haystack Observatory Westford, MA 01886

email: rps@haystack.mit.edu voice: 781-981-5767 www: http://www.haystack.mit.edu

jpetazzo commented 10 years ago

Hi Bob,

If I understand correctly, your suggestion would be to use logger.basicConfig() by default, "under the hood", unless some writable object was passed at some point?

Don't hesitate to give a little example, because I'm not 100% sure that I understand your suggestion.

Thank you!

schaefer0 commented 10 years ago

Jerome,

The short answer to your question:

If I understand correctly, your suggestion would be to use logger.basicConfig() by default, "under the hood", unless some writable object was passed at some point?

Is yes.

Here's the long answer:

I am coming from the perspective of building complex systems out of building-blocks like zeroRPC intended for low human-maintenance science experiments.

I have a bunch of server applications, some of which are daemons, some are started manually - all interacting with clients in a distributed system - some apps call proxies that call proxies. The application's purpose is to command and to log and monitoring those commands to a scientific radar for atmospheric research.

I have a bespoke log utility based on python's "logging" library that I configure, indicating what log directory to write to - the directory name includes a timestamp. It daily automatically closes the directory and reopens it with a new timestamp (the logger is driven by a thread). Each log file has a timestamp, I also automatically periodically close that file and reopen it (say 10 minutes to an hour - configurable by ini file). That way I have a timestamped directory of log info. Each service has its own log configuration ini file - so the directory looks like //.log

So, if I go away on the weekend and come back and find a crash of the application, I have a bounded set of directories and files to search for "error"s. Or if a scientist says something weird happened at UTC please check it, I can search the directories by date for particular "info".

I also have a process that monitors a computers disk space by percent full and emails me if it hits a disk full threshold or a radar position error, or a proxy fails to respond with a ping or a getStatus() command.

Right now I without being able to pass in my logger object to zeroRPC, I would have to run the zeroRPC service in a shell redirecting output to a log file that appends itself, and post-process the log file that on server error. With my bespoke logger I get a neatly organized set of directories.

By the way, ZeroRPC fits in very well with our long term plans for building software tools for science here.

Hope this helps.

bob s.

On Jan 23, 2014, at 2:15 PM, Jérôme Petazzoni wrote:

Hi Bob,

If I understand correctly, your suggestion would be to use logger.basicConfig() by default, "under the hood", unless some writable object was passed at some point?

Don't hesitate to give a little example, because I'm not 100% sure that I understand your suggestion.

Thank you!

— Reply to this email directly or view it on GitHub.

!DSPAM:52e16ea322079021468!


robert schaefer Atmospheric Sciences Group MIT Haystack Observatory Westford, MA 01886

email: rps@haystack.mit.edu voice: 781-981-5767 www: http://www.haystack.mit.edu

jpetazzo commented 10 years ago

(Sorry that it took almost 6 months to get back here...)

I have an extra question: are you using the zerorpc-client helper to run your server? Or is it your own code?

If you are using your own code, after thinking about it, I think your code should be the one setting up logging. IMHO it's a bad thing to try to setup logging automatically in a library. It might work in easy scenarios, but what if someone does import zerorpc first, then configures logging later?

However, I agree that we could provide better logging in zerorpc-client when running in server mode, if that makes sense.

schaefer0 commented 10 years ago

It’s ok for the delayed reply, its one of the drawbacks of open source I expect.

  1. I am not using zerorpc-client.
  2. What I would like to do is substitute my tailored logger for the zerorpc Server's default /basic logger on the Server() using the tailored logger as an optional parameter into the call. As an optional parameter, if I call the Server w/o the parameter, logging.basicConfig() has to be called first, as is expected now, but if I call it using the parameter, then “my" logger overrides. The advantage of “my" logger is that it has a thread that closes and opens directories where the log files are stored resulting in log file organization by date.

I am not sure if we are on the same page on this topic, but I recognize that my request is just that, a request (for an “optimization” that helps only me and I’m not sure if anyone else will find it useful.)

On Jul 3, 2014, at 9:12 AM, Jérôme Petazzoni notifications@github.com wrote:

(Sorry that it took almost 6 months to get back here...)

I have an extra question: are you using the zerorpc-client helper to run your server? Or is it your own code?

If you are using your own code, after thinking about it, I think your code should be the one setting up logging. IMHO it's a bad thing to try to setup logging automatically in a library. It might work in easy scenarios, but what if someone does import zerorpc first, then configures logging later?

However, I agree that we could provide better logging in zerorpc-client when running in server mode, if that makes sense.

— Reply to this email directly or view it on GitHub.

!DSPAM:53b571cb243592691326072!


robert schaefer Atmospheric Sciences Group MIT Haystack Observatory Westford, MA 01886

email: rps@haystack.mit.edu voice: 781-981-5767 www: http://www.haystack.mit.edu

bombela commented 9 years ago

I am not sure to understand the request completely. Feel free to re-open with more details.