BroadcastStuffGPCS.py (18098B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\net\BroadcastStuffGPCS.py 2 import sys 3 from collections import defaultdict 4 import blue 5 import bluepy 6 import uthread 7 from carbon.common.lib import const 8 from carbon.common.script.net import machoNet, machoNetAddress, machoNetPacket 9 from carbon.common.script.net.machoNetExceptions import UnMachoDestination 10 from carbon.common.script.sys import basesession 11 from carbon.common.script.sys.serviceConst import SERVICE_RUNNING, SERVICE_START_PENDING 12 from eveexceptions import UserError 13 14 class CoreBroadcastStuff: 15 __guid__ = 'gpcs.CoreBroadcastStuff' 16 __notifyRecvCount__ = defaultdict(lambda : 0) 17 __notifyMissedCount__ = defaultdict(lambda : 0) 18 __notifyRecvSourceCount__ = defaultdict(lambda : defaultdict(lambda : 0)) 19 __notifyMissedSourceCount__ = defaultdict(lambda : defaultdict(lambda : 0)) 20 21 def __init__(self): 22 self.machoNet = None 23 self.queue = [] 24 self.busrunning = 0 25 self.busrate = 333 26 27 def UpdateRecvNotificationStats(self, eventid, missed, source): 28 if source.addressType == const.ADDRESS_TYPE_NODE: 29 sourceId = source.nodeID 30 elif source.addressType == const.ADDRESS_TYPE_CLIENT: 31 sourceId = 'Client' 32 else: 33 sourceId = 'Unknown' 34 if missed: 35 CoreBroadcastStuff.__notifyMissedCount__[eventid] += 1 36 CoreBroadcastStuff.__notifyMissedSourceCount__[eventid][sourceId] += 1 37 else: 38 CoreBroadcastStuff.__notifyRecvCount__[eventid] += 1 39 CoreBroadcastStuff.__notifyRecvSourceCount__[eventid][sourceId] += 1 40 41 def __BusDriver(self): 42 try: 43 while 1: 44 blue.pyos.synchro.SleepWallclock(self.busrate) 45 if self.machoNet is None: 46 continue 47 if self.machoNet.state not in (SERVICE_START_PENDING, SERVICE_RUNNING) or machoNet.mode != 'server': 48 return 49 queue = self.queue 50 self.queue = [] 51 if queue: 52 if len(queue) == 1: 53 self.ScattercastWithoutTheStars(*queue[0]) 54 else: 55 self.ProxyBroadcast('__PacketBus', queue) 56 return 57 58 finally: 59 self.busrunning = 0 60 61 def NotifyUp(self, packet): 62 if packet.payload[0]: 63 self.machoNet.LogInfo('BroadcastStuff::Notify(', packet.destination.broadcastID, ',...)') 64 if packet.destination.broadcastID.startswith('Process'): 65 sm.ChainEventWithoutTheStars(packet.destination.broadcastID, packet.payload[1]) 66 elif packet.destination.broadcastID.startswith('Do'): 67 sm.SendEventWithoutTheStars(packet.destination.broadcastID, packet.payload[1]) 68 elif packet.destination.broadcastID == '__MultiEvent': 69 for broadcast in packet.payload[1]: 70 broadcastID, args = broadcast 71 if broadcastID.startswith('Process'): 72 sm.ChainEventWithoutTheStars(broadcastID, args) 73 elif broadcastID.startswith('Do'): 74 sm.SendEventWithoutTheStars(broadcastID, args) 75 else: 76 sm.ScatterEventWithoutTheStars(broadcastID, args) 77 78 elif packet.destination.broadcastID == '__PacketBus': 79 self.machoNet.LogInfo('PacketBus: handling a packet bus packet') 80 merge = {} 81 for each in packet.payload[1][0]: 82 k = (each[0], each[1]) 83 if k in merge: 84 merge[k].append((each[2], each[3])) 85 else: 86 merge[k] = [(each[2], each[3])] 87 88 for k, v in merge.iteritems(): 89 if len(v) > 1: 90 self.ScattercastWithoutTheStars(k[0], k[1], '__MultiEvent', v) 91 self.machoNet.LogInfo('PacketBus: scattercasting it to ', (k[0], k[1]), ' as __MultiEvent ', v) 92 else: 93 self.ScattercastWithoutTheStars(k[0], k[1], v[0][0], v[0][1]) 94 self.machoNet.LogInfo('PacketBus: scattercasting it to ', (k[0], k[1]), ' as ', v[0]) 95 96 else: 97 sm.ScatterEventWithoutTheStars(packet.destination.broadcastID, packet.payload[1]) 98 self.UpdateRecvNotificationStats(packet.destination.broadcastID, False, packet.source) 99 else: 100 packet.payload = packet.payload[1] 101 self.ForwardNotifyUp(packet) 102 103 def NotifyDown(self, packet): 104 packet.payload = (0, packet.payload) 105 self.ForwardNotifyDown(packet) 106 107 def Queuedcast(self, idtype, ids, method, *args): 108 with bluepy.Timer('machoNet::Queuedcast'): 109 callTimer = basesession.CallTimer('Queuedcast::%s::%s (Broadcast\\Client)' % (method, idtype)) 110 try: 111 return self.QueuedcastWithoutTheStars(idtype, ids, method, args) 112 finally: 113 callTimer.Done() 114 115 def QueuedcastWithoutTheStars(self, idtype, ids, method, args): 116 if ids: 117 self.queue.append((idtype, 118 tuple(ids), 119 method, 120 args)) 121 if not self.busrunning: 122 self.busrunning = 1 123 uthread.worker('MachoNet::BroadcastStuff::BusDriver', self.__BusDriver) 124 125 def Scattercast(self, idtype, ids, method, *args): 126 with bluepy.Timer('machoNet::Scattercast'): 127 callTimer = basesession.CallTimer('Scattercast::%s::%s (Broadcast\\Client)' % (method, idtype)) 128 try: 129 return self.ScattercastWithoutTheStars(idtype, ids, method, args) 130 finally: 131 callTimer.Done() 132 133 def ScattercastWithoutTheStars(self, idtype, ids, method, args): 134 if not idtype.startswith('+'): 135 idtype = '*%s' % idtype 136 if ids: 137 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype=idtype, narrowcast=ids), payload=(1, args))) 138 139 def Objectcast(self, object, method, *args): 140 with bluepy.Timer('machoNet::Objectcast'): 141 callTimer = basesession.CallTimer('Objectcast::%s (Broadcast\\Client)' % method) 142 try: 143 self.ObjectcastWithoutTheStars(object, method, args) 144 finally: 145 callTimer.Done() 146 147 def ObjectcastWithoutTheStars(self, object, method, args): 148 objectID = basesession.GetObjectUUID(object) 149 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='objectID', narrowcast=[objectID]), payload=(1, args))) 150 151 def Broadcast(self, method, *args): 152 with bluepy.Timer('machoNet::Broadcast'): 153 callTimer = basesession.CallTimer('Broadcast::%s (Broadcast\\Client)' % method) 154 try: 155 packet = machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method), payload=(1, args)) 156 self.ForwardNotifyDown(packet) 157 finally: 158 callTimer.Done() 159 160 def ClientBroadcast(self, method, *args): 161 with bluepy.Timer('machoNet::ClientBroadcast'): 162 callTimer = basesession.CallTimer('ClientBroadcast::%s (Broadcast\\Client)' % method) 163 try: 164 packet = machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='clientID'), payload=(1, args)) 165 self.ForwardNotifyDown(packet) 166 finally: 167 callTimer.Done() 168 169 def ClusterBroadcast(self, method, *args): 170 with bluepy.Timer('machoNet::ClusterBroadcast'): 171 callTimer = basesession.CallTimer('ClusterBroadcast::%s (Broadcast\\Client)' % method) 172 try: 173 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='nodeID'), payload=(1, args))) 174 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='+nodeID', narrowcast=self.machoNet.GetConnectedProxyNodes()), payload=(1, args))) 175 if method.startswith('Process'): 176 sm.ChainEventWithoutTheStars(method, args) 177 elif method.startswith('Do'): 178 sm.SendEventWithoutTheStars(method, args) 179 else: 180 sm.ScatterEventWithoutTheStars(method, args) 181 finally: 182 callTimer.Done() 183 184 def ServerBroadcast(self, method, *args): 185 with bluepy.Timer('machoNet::ServerBroadcast'): 186 callTimer = basesession.CallTimer('ServerBroadcast::%s (Broadcast\\Client)' % method) 187 try: 188 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='nodeID'), payload=(1, args))) 189 if machoNet.mode == 'server': 190 if method.startswith('Process'): 191 sm.ChainEventWithoutTheStars(method, args) 192 elif method.startswith('Do'): 193 sm.SendEventWithoutTheStars(method, args) 194 else: 195 sm.ScatterEventWithoutTheStars(method, args) 196 finally: 197 callTimer.Done() 198 199 NodeBroadcast = ServerBroadcast 200 201 def NarrowcastByNodeIDsWithoutTheStars(self, nodeids, method, args, kwargs): 202 if len(nodeids): 203 if 'sourceNodeID' in kwargs: 204 source = machoNetAddress.MachoAddress(nodeID=kwargs['sourceNodeID'], service=None, callID=None) 205 else: 206 source = machoNetAddress.MachoAddress() 207 destination = machoNetAddress.MachoAddress(broadcastID=method, idtype='nodeID', narrowcast=nodeids) 208 self.ForwardNotifyDown(machoNetPacket.Notification(source=source, destination=destination, payload=(1, args))) 209 210 def NarrowcastByNodeIDs(self, nodeids, method, *args, **kwargs): 211 with bluepy.Timer('machoNet::NarrowcastByNodeIDs'): 212 callTimer = basesession.CallTimer('NarrowcastByClientIDs::%s (Broadcast\\Client)' % method) 213 try: 214 self.NarrowcastByNodeIDsWithoutTheStars(nodeids, method, args, kwargs) 215 finally: 216 callTimer.Done() 217 218 def SinglecastByServiceMaskWithoutTheStars(self, serviceMask, method, args, kwargs): 219 destination = machoNetAddress.MachoAddress(broadcastID=method, idtype='serviceMask', narrowcast=[serviceMask]) 220 source = machoNetAddress.MachoAddress() 221 self.ForwardNotifyDown(machoNetPacket.Notification(source=source, destination=destination, payload=(1, args))) 222 if machoNet.mode == 'server' and self.machoNet.serviceMask & serviceMask: 223 if method.startswith('Process'): 224 sm.ChainEventWithoutTheStars(method, args) 225 elif method.startswith('Do'): 226 sm.SendEventWithoutTheStars(method, args) 227 else: 228 sm.ScatterEventWithoutTheStars(method, args) 229 230 def SinglecastByServiceMask(self, serviceMask, method, *args, **kwargs): 231 with bluepy.Timer('machoNet::SinglecastByServiceMask'): 232 callTimer = basesession.CallTimer('SinglecastByServiceMask:: %s (Broadcast\\Client)' % method) 233 try: 234 self.SinglecastByServiceMaskWithoutTheStars(serviceMask, method, args, kwargs) 235 finally: 236 callTimer.Done() 237 238 def SinglecastByNodeID(self, nodeid, method, *args, **kwargs): 239 with bluepy.Timer('machoNet::SinglecastByNodeID'): 240 callTimer = basesession.CallTimer('SinglecastByNodeID::%s (Broadcast\\Client)' % method) 241 try: 242 self.NarrowcastByNodeIDsWithoutTheStars([nodeid], method, args, kwargs) 243 finally: 244 callTimer.Done() 245 246 def ProxyBroadcast(self, method, *args): 247 with bluepy.Timer('machoNet::ProxyBroadcast'): 248 callTimer = basesession.CallTimer('ProxyBroadcast::%s (Broadcast\\Client)' % method) 249 try: 250 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='+nodeID', narrowcast=self.machoNet.GetConnectedProxyNodes()), payload=(1, args))) 251 if machoNet.mode == 'proxy': 252 if method.startswith('Process'): 253 sm.ChainEventWithoutTheStars(method, args) 254 elif method.startswith('Do'): 255 sm.SendEventWithoutTheStars(method, args) 256 else: 257 sm.ScatterEventWithoutTheStars(method, args) 258 finally: 259 callTimer.Done() 260 261 def NarrowcastByClientIDs(self, clientids, method, *args): 262 with bluepy.Timer('machoNet::NarrowcastByClientIDs'): 263 callTimer = basesession.CallTimer('NarrowcastByClientIDs::%s (Broadcast\\Client)' % method) 264 try: 265 return self.NarrowcastByClientIDsWithoutTheStars(clientids, method, args) 266 finally: 267 callTimer.Done() 268 269 def NarrowcastByClientIDsWithoutTheStars(self, clientids, method, args): 270 if len(clientids): 271 packet = machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='clientID', narrowcast=clientids), payload=(1, args)) 272 self.ForwardNotifyDown(packet) 273 274 def SinglecastByClientID(self, clientid, method, *args): 275 with bluepy.Timer('machoNet::SinglecastByClientID'): 276 callTimer = basesession.CallTimer('SinglecastByClientID::%s (Broadcast\\Client)' % method) 277 try: 278 self.NarrowcastByClientIDsWithoutTheStars([clientid], method, args) 279 finally: 280 callTimer.Done() 281 282 def ReliableSinglecastByUserID(self, userid, method, *args): 283 with bluepy.Timer('machoNet::ReliableSinglecastByUserID'): 284 callTimer = basesession.CallTimer('ReliableSinglecastByUserID::%s (Broadcast\\Client)' % method) 285 try: 286 clientIDs = sm.GetService('sessionMgr').GetClientIDsFromID('userid', userid, refresh=1) 287 self.NarrowcastByClientIDsWithoutTheStars(clientIDs, method, args) 288 except UnMachoDestination as e: 289 self.machoNet.LogInfo('User ', userid, " was not reachable, so he didn't get this singlecast. Should be fine and dandy. reason=", e.payload) 290 sys.exc_clear() 291 except UserError as e: 292 if e.msg != 'UnMachoDestination': 293 raise 294 self.machoNet.LogInfo('User ', userid, " was not reachable, so he didn't get this singlecast. Should be fine and dandy. reason=", e.msg) 295 sys.exc_clear() 296 finally: 297 callTimer.Done() 298 299 def NarrowcastByUserIDs(self, userids, method, *args): 300 if not userids: 301 return 302 with bluepy.Timer('machoNet::NarrowcastByUserIDs'): 303 callTimer = basesession.CallTimer('NarrowcastByUserIDs::%s (Broadcast\\Client)' % method) 304 try: 305 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='userid', narrowcast=userids), payload=(1, args))) 306 finally: 307 callTimer.Done() 308 309 def SinglecastByUserID(self, userid, method, *args): 310 with bluepy.Timer('machoNet::SinglecastByUserID'): 311 callTimer = basesession.CallTimer('SinglecastByUserID::%s (Broadcast\\Client)' % method) 312 try: 313 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='userid', narrowcast=[userid]), payload=(1, args))) 314 finally: 315 callTimer.Done() 316 317 def ReliableSinglecastByCharID(self, charid, method, *args): 318 with bluepy.Timer('machoNet::ReliableSinglecastByCharID'): 319 callTimer = basesession.CallTimer('ReliableSinglecastByCharID::%s (Broadcast\\Client)' % method) 320 try: 321 clientIDs = sm.GetService('sessionMgr').GetClientIDsFromID('charid', charid, refresh=1) 322 self.NarrowcastByClientIDsWithoutTheStars(clientIDs, method, args) 323 except UnMachoDestination as e: 324 self.machoNet.LogInfo('Character ', charid, " was not reachable, so he didn't get this singlecast. Should be fine and dandy. reason=", e.payload) 325 sys.exc_clear() 326 except UserError as e: 327 if e.msg != 'UnMachoDestination': 328 raise 329 self.machoNet.LogInfo('Character ', charid, " was not reachable, so he didn't get this singlecast. Should be fine and dandy. reason=", e.msg) 330 sys.exc_clear() 331 finally: 332 callTimer.Done() 333 334 def NarrowcastByCharIDs(self, charids, method, *args): 335 if not charids: 336 return 337 with bluepy.Timer('machoNet::NarrowcastByCharIDs'): 338 callTimer = basesession.CallTimer('NarrowcastByCharIDs::%s (Broadcast\\Client)' % method) 339 try: 340 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='charid', narrowcast=charids), payload=(1, args))) 341 finally: 342 callTimer.Done() 343 344 def SinglecastByCharID(self, charid, method, *args): 345 with bluepy.Timer('machoNet::SinglecastByCharID'): 346 callTimer = basesession.CallTimer('SinglecastByCharID::%s (Broadcast\\Client)' % method) 347 try: 348 self.ForwardNotifyDown(machoNetPacket.Notification(destination=machoNetAddress.MachoAddress(broadcastID=method, idtype='charid', narrowcast=[charid]), payload=(1, args))) 349 finally: 350 callTimer.Done()