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.

Reply via email to