Overloaded UDP Device advice

I'm looking for advice on how to handle an issue I'm trying to solve.

I'm using a UDP device in the ignition OPCUA Server to receive a data stream from an existing service at my facility. There is a fleet of tools(roughly 250) that use the service to forward me(and another server) their tag information. I have a tag change script that generates the tags of the device from the UDP string. Each tool sends data on a ten second interval. To be clear the Tools message the service, the service then messages me(on just one port =/) as well as other subscribers.

My issue seems to be that if the packets from multiple tools arrive within the same evaluation cycle of the tag group of the UDP Device Message tag, only one is evaluated. This will result in dropped packets and the occasional loss of comm false alarm.

I've also tried approaching this without the OPCUA server. I attempted to have a startup script that asynchronously evaluates the UDP packets as they come in, but haven't had much success there. I learned quickly that you need to store the socket as a global and close it with the gateway! Anyway, something seems wrong with my async scripting as the loggers aren't logging.

My backup plan is to utilize the MQTT engine, the service mentioned above is also feeding into a mqtt broker.

EDIT:
Did some more debugging today:
Getting a SystemUtilities logger error: Error running function from system.util.invokeAsynchronous.
Specifically, NameError: global name 'MFG' is not defined.
MFG is a script in the project library of the project that has the startup script and is also the gateway scripting project. MFG is where the function that does the parsing lives. Oddly, I can run the parsing function from MFG via a tag change script when I try using the opcua strategy above. I'm not sure why the Startup Script can't see it.

EDIT2:
Was able to get the script async pulling in data from the UDP port. Oddly I can't get more than 2048 bytes. The expected packets are 10500ish bytes.
I'm passing 16384 to socket.recv but stilling getting truncated data.

def read_udp():
	import socket
	import system
	import MFG
	
	UDP_IP = "10.4.16.69"
	UDP_PORT = 49401
	read_udp_logger = system.util.getLogger("read_udp")
	read_udp_logger.info("starting read_udp socket")
	
	sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 65535)
	sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 65535)
	read_udp_logger.info(str(sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)))
	sock.bind((UDP_IP, UDP_PORT))
	system.util.globals['udp_socket'] = socket
	while True:
		try:
			"""BUFF_SIZE = 2048
			data =''
			while True:
				part = sock.recv(BUFF_SIZE)
				data += part
				if len(part) < BUFF_SIZE:
			 		# either 0 or end of data
					break"""
			#read_udp_logger.trace(str(sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)))
			#data = bytearray(65535)
			#bytesRec, addr = sock.recvfrom_into(data)
			data = sock.recv(65535)
			#read_udp_logger.trace("bytes recv: " + str(bytesRec))
			read_udp_logger.trace("len of casted str: " + str(len(str(data))))
			read_udp_logger.trace(str(data))
			result = MFG.parseTools(data)
			print(str(result))
		except Exception as e:
			read_udp_logger.debug(str(e))
		
		
logger = system.util.getLogger("startup_script")
logger.info("starting read_udp socket")
system.util.invokeAsynchronous(read_udp)

Open your own UDP socket with Netty (exposed to OPC drivers, not sure about gateway-wide). Then you can obtain the source address of any packet aimed at your socket, and multiplex as needed. I do similar with my EtherNet/IP driver.

Thanks for the advice!
I was able to get UDP ingestion working 90% with python sockets.

Oddly they are being truncated to 2048 despite my passing 16384 (or even 65535) to recv. I also set SO_RCVBUF to higher values.
After some googling I found someone experiencing a similar issue with Netty
I'm curious if I'm experiencing the same issue.

Out of curiosity do you go beyond 2048 bytes in you ethernet/IP driver Phil?

It is theoretically capable of handling jumbo UDP packets, but I don't have anything that would test it. {Hmm. Maybe pointing two different copies of my module at each other. I have jumbo infra available.}

Anyways, any time a UDP packet exceeds the MTU of your ethernet layer (1560 bytes of ethernet frame, IIRC), the packet will be fragmented. I haven't messed with UDP fragmentation, sorry.

I don't ever use the jython socket module. Or any jython I/O modules. Too much python 2 ambiguity, old implementations, and encoding hassles.