2011-12-03 12 views
5

Tak więc, robię to, pisząc usługę strumieniowania WSGI, która wykorzystuje kolejkę owiniętą w iteratorze, aby zaimplementować wysyłanie grupowe. Poniżej jest to uproszczony model usługi:Wdrażanie usługi strumieniowej WSGI: (jak wykrywać rozłączenia klientów)

# this is managed by another thread 
def processor_runner(): 
    generator = SerialMessageGenerator() 
    for message in generator: 
     for client in Processor.connections: 
      client.put(message) 

# this is managed by twisted's wsgi implementation 
def main(environ, start_response): 
    queue = Queue() 
    Processor.connections.append(queue) 
    status = '200 OK' 
    response_headers = [ 
     ('Content-Type', 'application/json'), 
     ('Transfer-Encoding', 'chunked') 
    ] 
    start_response(status, response_headers) 
    return iter(queue.get, None) 

I działa doskonale z skręcona jako serwer WSGI (jako bok generator szeregowe jest oddzielny proces połączony z procesorem w kolejce między procesu) . Moje pytanie brzmi: jak mogę wykryć, kiedy klient rozłącza się i tym samym usuwa go z kolejki? Moim jednak jest dodanie kolejki jako krotki z gniazdem klienta, tj. (Gniazdo, kolejka), a następnie sprawdzenie, czy gniazdo jest nadal podłączone przed wykonaniem instalacji. Jednak nie wiem dokładnie, co pobrać ze środowiska. Czy ktokolwiek ma jakieś doświadczenie z robieniem tego, zanim coś zhakuję?

Updated

Oto rozwiązanie I w końcu poszedł z:

class IterableQueue(Queue): 

def __init__(self): 
    Queue.__init__(self) # Queue is an old style class 
    ShellProcessor.connections.append(self) 

def __iter__(self): 
    return iter(self.get, None) 

def close(self): 
    self.put(None) 
    self.task_done() 
    ShellProcessor.connections.remove(self) 
+0

także czuć się swobodnie wypowiedzieć się na temat architektury lub wykonania usługi streamingu WSGI jeśli masz jakiekolwiek doświadczenie. – Bashwork

Odpowiedz

1

połączenia skręcone .close() w iteratorze, jeśli występuje, gdy żądanie zostanie zakończone lub przerwane. Można zrobić coś takiego:

# ... 
start_response(status, response_headers) 
return ResponseIterator(iter(queue.get, None), 
    on_finish=lambda: Processor.connections.remove(queue)) 

gdzie ResponseIterator mogą być:

class ResponseIterator: 

    def __init__(self, iterator, on_finish=None): 
     self.iterator = iterator 
     self.on_finish = on_finish 

    def __iter__(self): 
     return self 

    def next(self): 
     return next(self.iterator) 

    def close(self): 
     if self.on_finish is not None: 
     self.on_finish() 
+0

Miło, nie wiedziałem, że to się nazywa blisko iteratora. To jest doskonałe! – Bashwork

Powiązane problemy