11import os
2+ import json
23import uuid
4+ import time
35import asyncio
46import logging
7+ import copy
58
69from .config import ReceptorConfig
710from .router import MeshRouter
@@ -20,6 +23,9 @@ def __init__(self, config=None, node_id=None, router_cls=None,
2023 self .work_manager = (work_manager_cls or WorkManager )(self )
2124 self .connections = dict ()
2225 self .controller_connections = []
26+ self .connection_manifest_path = os .path .join (self .config .server .data_dir ,
27+ self .node_id ,
28+ "connection_manifest" )
2329 self .stop = False
2430
2531 def _find_node_id (self ):
@@ -32,31 +38,80 @@ def _find_node_id(self):
3238 ofs .write (f'\n RECEPTOR_NODE_ID={ node_id } \n ' )
3339 return str (node_id )
3440
41+ async def watch_expire (self ):
42+ while True :
43+ current_manifest = self .get_connection_manifest ()
44+ for connection in current_manifest :
45+ buffer = self .config .components .buffer_manager .get_buffer_for_node (connection ["id" ], self )
46+ for ident , message in buffer :
47+ message_actual = json .loads (message )
48+ if "expire_time" in message_actual and message_actual ['expire_time' ] < time .time ():
49+ buffer .read_message (ident , remove = True )
50+ logger .info ("Expiring message {}:{}" .format (ident , connection ["id" ]))
51+ # TODO: Do something with expired message
52+ if connection ["last" ] + 86400 < time .time ():
53+ logger .info ("Expiring connection {}" .format (connection ["id" ]))
54+ write_manifest = copy .copy (current_manifest )
55+ write_manifest .remove (connection )
56+ self .write_connection_manifest (write_manifest )
57+ await asyncio .sleep (600 )
58+
59+ def get_connection_manifest (self ):
60+ if not os .path .exists (self .connection_manifest_path ):
61+ return []
62+ try :
63+ fd = open (self .connection_manifest_path , "r" )
64+ manifest = json .load (fd )
65+ return manifest
66+ except Exception as e :
67+ logger .warn ("Failed to read connection manifest: {}" .format (e ))
68+ return []
69+
70+ def write_connection_manifest (self , manifest ):
71+ fd = open (self .connection_manifest_path , "w" )
72+ json .dump (manifest , fd )
73+ fd .close ()
74+
75+ def update_connection_manifest (self , connection ):
76+ manifest = self .get_connection_manifest ()
77+ found = False
78+ for node in manifest :
79+ if node ["id" ] == connection :
80+ node ["last" ] = time .time ()
81+ found = True
82+ break
83+ if not found :
84+ manifest .append (dict (id = connection ,
85+ last = time .time ()))
86+ self .write_connection_manifest (manifest )
87+
3588 def update_connections (self , connection ):
3689 self .router .register_edge (connection .id_ , self .node_id , 1 )
3790 if connection .id_ in self .connections :
3891 self .connections [connection .id_ ].append (connection )
3992 else :
4093 self .connections [connection .id_ ] = [connection ]
94+ self .update_connection_manifest (connection .id_ )
4195
4296 def add_connection (self , id_ , protocol_obj ):
4397 buffer_mgr = self .config .components .buffer_manager
4498 conn = Connection (id_ , protocol_obj , buffer_mgr , self )
4599 self .update_connections (conn )
46100 return conn
47101
48- def remove_connection (self , conn ):
49- notify_protocols = []
102+ def remove_connection (self , protocol_obj ):
103+ notify_connections = []
50104 for connection_node in self .connections :
51- if conn in self .connections [connection_node ]:
52- logger .info ("Removing connection {} for node {}" .format (conn , connection_node ))
53- self .connections [connection_node ].remove (conn )
105+ if protocol_obj in self .connections [connection_node ]:
106+ logger .info ("Removing connection {} for node {}" .format (protocol_obj , connection_node ))
107+ self .update_connection_manifest (connection_node )
108+ self .connections [connection_node ].remove (protocol_obj )
54109 self .router .update_node (self .node_id , connection_node , 100 )
55110 self .router .debug_router ()
56- notify_protocols += self .connections [ connection_node ]
57- # TODO: Broadcast update, set timer for full expiration
58- for active_protocol in notify_protocols :
59- active_protocol .send_route_advertisement (self .router .get_edges ())
111+ self .update_connection_manifest ( connection_node )
112+ notify_connections += self . connections [ connection_node ]
113+ for active_connection in notify_connections :
114+ active_connection .send_route_advertisement (self .router .get_edges ())
60115
61116 async def shutdown_handler (self ):
62117 while True :
0 commit comments