view patchsink.py @ 12:032e59be8fe9

refactor to separate the nonweb stuff a bit, in prep for cyclone->starlette
author drewp@bigasterisk.com
date Fri, 25 Nov 2022 20:58:08 -0800
parents
children bfd95926be6e
line wrap: on
line source

import time
from typing import Dict

import cyclone.sse
import cyclone.web

class PatchSink(cyclone.sse.SSEHandler):
    _handlerSerial = 0

    def __init__(self, application: cyclone.web.Application, request):
        cyclone.sse.SSEHandler.__init__(self, application, request)
        self.bound = False
        self.created = time.time()
        self.graphClients = self.settings.graphClients

        self._serial = PatchSink._handlerSerial
        PatchSink._handlerSerial += 1
        self.lastPatchSentTime: float = 0.0

    def __repr__(self) -> str:
        return '<Handler #%s>' % self._serial

    def state(self) -> Dict:
        return {
            'created': round(self.created, 2),
            'ageHours': round((time.time() - self.created) / 3600, 2),
            'streamId': self.streamId,
            'remoteIp': self.request.remote_ip,  # wrong, need some forwarded-for thing
            'foafAgent': self.request.headers.get('X-Foaf-Agent'),
            'userAgent': self.request.headers.get('user-agent'),
        }

    def bind(self, *args, **kwargs):
        self.streamId = args[0]

        self.graphClients.addSseHandler(self)
        # If something goes wrong with addSseHandler, I don't want to
        # try removeSseHandler.
        self.bound = True

    def unbind(self) -> None:
        if self.bound:
            self.graphClients.removeSseHandler(self)