示例#1
0
def unlocked():
    """
    Context manager which unlocks a Document and dispatches
    ModelChangedEvents triggered in the context body to all sockets
    on current sessions.
    """
    curdoc = state.curdoc
    if curdoc is None or curdoc.session_context is None or curdoc.session_context.session is None:
        yield
        return
    from tornado.websocket import WebSocketHandler
    connections = curdoc.session_context.session._subscribed_connections

    hold = curdoc.callbacks.hold_value
    if hold:
        old_events = list(curdoc.callbacks._held_events)
    else:
        old_events = []
        curdoc.hold()
    try:
        yield

        locked = False
        for conn in connections:
            socket = conn._socket
            if hasattr(socket,
                       'write_lock') and socket.write_lock._block._value == 0:
                locked = True
                break

        events = []
        for event in curdoc.callbacks._held_events:
            if not isinstance(
                    event, ModelChangedEvent) or event in old_events or locked:
                events.append(event)
                continue
            for conn in connections:
                socket = conn._socket
                ws_conn = getattr(socket, 'ws_connection', False)
                if (not hasattr(socket, 'write_message') or ws_conn is None
                        or (ws_conn and ws_conn.is_closing())):
                    continue
                msg = conn.protocol.create('PATCH-DOC', [event])
                WebSocketHandler.write_message(socket, msg.header_json)
                WebSocketHandler.write_message(socket, msg.metadata_json)
                WebSocketHandler.write_message(socket, msg.content_json)
                for header, payload in msg._buffers:
                    WebSocketHandler.write_message(socket, header)
                    WebSocketHandler.write_message(socket,
                                                   payload,
                                                   binary=True)
        curdoc.callbacks._held_events = events
    finally:
        if hold:
            return
        try:
            curdoc.unhold()
        except RuntimeError:
            curdoc.add_next_tick_callback(
                partial(_dispatch_events, curdoc, events))
示例#2
0
def unlocked():
    """
    Context manager which unlocks a Document and dispatches
    ModelChangedEvents triggered in the context body to all sockets
    on current sessions.
    """
    curdoc = state.curdoc
    if curdoc is None or curdoc.session_context is None or curdoc.session_context.session is None:
        yield
        return
    connections = curdoc.session_context.session._subscribed_connections

    hold = curdoc._hold
    if hold:
        old_events = list(curdoc._held_events)
    else:
        old_events = []
        curdoc.hold()
    try:
        yield
        events = []
        for conn in connections:
            socket = conn._socket
            if hasattr(socket,
                       'write_lock') and socket.write_lock._block._value == 0:
                state._locks.add(socket)
            locked = socket in state._locks
            for event in curdoc._held_events:
                if (isinstance(event, ModelChangedEvent)
                        and event not in old_events
                        and hasattr(socket, 'write_message') and not locked):
                    msg = conn.protocol.create('PATCH-DOC', [event])
                    WebSocketHandler.write_message(socket, msg.header_json)
                    WebSocketHandler.write_message(socket, msg.metadata_json)
                    WebSocketHandler.write_message(socket, msg.content_json)
                    for header, payload in msg._buffers:
                        WebSocketHandler.write_message(socket, header)
                        WebSocketHandler.write_message(socket,
                                                       payload,
                                                       binary=True)
                elif event not in events:
                    events.append(event)
        curdoc._held_events = events
    finally:
        if not hold:
            curdoc.unhold()