Thanks. I'll try your suggestion.

On Thu, Aug 9, 2018 at 8:03 PM, Graham Dumpleton <[email protected]
> wrote:

> For a start, you should be doing something like:
>
>     try:
>         context = zmq.Context()
>         #print "Connecting to server..." - commented out based on your
> answer
>         socket = context.socket(zmq.DEALER)
>         socket.connect ("ipc://%s" % ipc_sock)
>
>         try:
>
>         # socket.setsockopt(zmq.SOCKOPT_LINGER, 0) this should be the
> default for close() and is not in python binding
>         poll = zmq.Poller()
>         poll.register(socket, zmq.POLLIN)
>
>         socket.send_string (send_msg)
>         socks = dict(poll.poll(REQUEST_TIMEOUT))
>
>         if socket in socks and socks[socket] == zmq.POLLIN:
>             reply_msg = socket.recv()
>             if '"Error":' not in reply_msg:
>                 cur_ms = time.time()
>                 elapsed_ms = cur_ms - start_ms
>                 reply_msg = '{"Data": ' + reply_msg + ',"Resp_time": "' +
> str(elapsed_ms) + '"}'
>         else:
>             reply_msg = '{"Error": "No Response from CMDSRV in ' +
> str(REQUEST_TIMEOUT) + ' milliseconds"' + alert_param
>
>         socket.setsockopt(zmq.LINGER, 0)
>
> finally:
>         socket.close()
>         try:
>             poll.unregister(socket)
>         except Exception:
>             pass
>
>
>     except Exception as e:
>         reply_msg = '{"Error": "' + e.message + '"' + alert_param
>
> This way if an error occurs and exception passed back, that you ensure you
> close the socket promptly, and potentially deregister it from the poller if
> necessary.
>
> If don't do that for errors, socket may stay open.
>
> Graham
>
> On 10 Aug 2018, at 9:58 am, Tim Moody <[email protected]> wrote:
>
> If it is not an imposition here is the entire app:
>
> import zmq
> import os.path
> import time
> import urllib2
>
> cmdsrv_pid_file = "{{ cmdsrv_pid_file }}"
> cmdsrv_ready_file = "{{ cmdsrv_ready_file }}"
>
> alert_param = ',"Alert": "True"}'
>
> def application(environ, start_response):
>     start_ms = time.time()
>
>     if environ['REQUEST_METHOD'] == 'POST':
>         try:
>             request_body_size = int(environ.get('CONTENT_LENGTH', 0))
>         except (ValueError):
>             request_body_size = 0
>
>         request_body = environ['wsgi.input'].read(request_body_size)
>         # request_body holds command=<text of cmd>
>
>         if os.path.exists(cmdsrv_pid_file):
>             if os.path.exists(cmdsrv_ready_file):
>                 # unpack cmd, urldecode, and substitute space for %20
>                 cmd = urllib2.unquote(request_body.
> split('=')[1]).decode('utf8')
>                 cmd = cmd.replace('%20', ' ')
>
>                 response_body = send_command(cmd, start_ms)
>             else:
>                 response_body = '{"Error": "CMDSRV has started but is not
> ready."' + alert_param
>         else:
>             response_body = '{"Error": "CMDSRV is not running."' +
> alert_param
>
>         response_headers = [('Content-type', 'application/json'),
> ('Content-Length', str(len(response_body)))]
>
>     else: # not a POST
>         response_body = dump(environ)
>         response_headers = [('Content-type', 'text/plain'),
>                        ('Content-Length', str(len(response_body)))]
>     status = '200 OK'
>     start_response(status, response_headers)
>     return [response_body]
>
> def dump(environ):
>     response_body = ['%s: %s' % (key, value) for key, value in
> sorted(environ.items())]
>     response_body = '\n'.join(response_body)
>     return response_body
>
> def send_command(cmd, start_ms):
>
>     REQUEST_TIMEOUT = 30000
>     send_msg = cmd
>
>     ipc_sock = "/run/cmdsrv_sock"
>
>     try:
>         context = zmq.Context()
>         #print "Connecting to server..." - commented out based on your
> answer
>         socket = context.socket(zmq.DEALER)
>         socket.connect ("ipc://%s" % ipc_sock)
>         # socket.setsockopt(zmq.SOCKOPT_LINGER, 0) this should be the
> default for close() and is not in python binding
>         poll = zmq.Poller()
>         poll.register(socket, zmq.POLLIN)
>
>         socket.send_string (send_msg)
>         socks = dict(poll.poll(REQUEST_TIMEOUT))
>
>         if socket in socks and socks[socket] == zmq.POLLIN:
>             reply_msg = socket.recv()
>             if '"Error":' not in reply_msg:
>                 cur_ms = time.time()
>                 elapsed_ms = cur_ms - start_ms
>                 reply_msg = '{"Data": ' + reply_msg + ',"Resp_time": "' +
> str(elapsed_ms) + '"}'
>         else:
>             reply_msg = '{"Error": "No Response from CMDSRV in ' +
> str(REQUEST_TIMEOUT) + ' milliseconds"' + alert_param
>
>         socket.setsockopt(zmq.LINGER, 0)
>         socket.close()
>         poll.unregister(socket)
>
>     except Exception as e:
>         reply_msg = '{"Error": "' + e.message + '"' + alert_param
>
>     return reply_msg
>
>
> On Thu, Aug 9, 2018 at 7:48 PM, Tim Moody <[email protected]> wrote:
>
>> Well, I think it is thread safe. The mod_wsgi application is an end point
>> for an ajax request, which it forwards to the multi-threaded backend server
>> over a zeromq socket (using a linux ipc socket), polls for a response for
>> up to 30 seconds, and returns the json result or failure to the ajax
>> caller's callback function. It then terminates. All of this is password
>> protected using apache mod_auth, part of the reason I didn't just use uwsgi.
>>
>>
>> On Thu, Aug 9, 2018 at 7:30 PM, Graham Dumpleton <
>> [email protected]> wrote:
>>
>>>
>>>
>>> > On 10 Aug 2018, at 9:22 am, Tim Moody <[email protected]> wrote:
>>> >
>>> > Thanks for replying so quickly. The message is indeed a print
>>> statement in my python wrapper. It was the wsgi.error that threw me off. So
>>> I guess it is really an info message.
>>> >
>>> > However, I still get failed connections, but perhaps these are from
>>> zeromq and not from mod_wsgi. However, to be sure, I should say that I am
>>> not using WSGIDaemonProcess but only WSGIScriptAlias and all other defaults
>>> (on 4.3.0 Ubuntu 16.04). Is there any chance that mod_wsgi will be starved
>>> for connections if 8 requests arrive nearly simultaneously?
>>>
>>> Is your use of the client for backend service thread safe?
>>>
>>> A typical configuration for Apache/mod_wsgi means that you have multiple
>>> threads per process handling requests, so you have to be careful to ensure
>>> that each request has own client instance, or if one client instance that
>>> can handle multithread access okay.
>>>
>>> Anyway, how many concurrent requests mod_wsgi can handle for embedded
>>> mode is dictated by Apache MPM settings. This is unrelated though to
>>> backend connections and whether limits enforced by backend service. If
>>> capacity to handle more requests had been reached as Apache MPM settings
>>> low, requests would just queue up and never get to the application until
>>> free capacity, so not going to affect anything in backend connections for
>>> those requests which are able to be handled.
>>>
>>> Graham
>>>
>>> --
>>> You received this message because you are subscribed to a topic in the
>>> Google Groups "modwsgi" group.
>>> To unsubscribe from this topic, visit https://groups.google.com/d/to
>>> pic/modwsgi/HMKpmmNacX4/unsubscribe.
>>> To unsubscribe from this group and all its topics, send an email to
>>> [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at https://groups.google.com/group/modwsgi.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "modwsgi" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/modwsgi.
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "modwsgi" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/modwsgi/HMKpmmNacX4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/modwsgi.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"modwsgi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/modwsgi.
For more options, visit https://groups.google.com/d/optout.

Reply via email to