Ich schreibe einen Server in Erlang, der sehr viele Nachrichten (Datensätze) verarbeitet. Jede Nachricht hat ein Tag (Atom) wie eine Benutzer-ID.Routing von Nachrichten an PIDs in Erlang
Der "Router" erstellt einen dedizierten permanenten Prozess für diesen Benutzer (um Nachrichten für einige Minuten zu sammeln, bevor sie gespeichert und weitergegeben werden), wenn ein solcher Prozess nicht existiert. Andernfalls wird es als Nachricht an das vorhandene Prozesspostfach übergeben.
Das Problem ist die Buchhaltung einer Routing-Tabelle.
Ich könnte denken, Serialisierung des Routers, jede Nachricht wird in ETS-Lookup zu finden, eine PID von userId und schließlich Spawn und ETS einfügen, wenn es nicht beendet. Aber das wurde in wenigen Sekunden verstopft.
Eine Alternative ist es, einen Prozess direkt zu routen, um jede Nachricht zu routen, aber das könnte zu einem Race-Zustand führen, wenn einige Nachrichten an einen einzelnen Benutzer in naher Folge eintraten und ihre entsprechende PID in ETS nicht gefunden und dauerhaft erzeugt wurden Prozesse. Nachrichten gehen verloren und nur der letzte erzeugte Prozess wird gültig sein (andere in der ETS überschreiben), wo die anderen inaktiv und nicht geparkt werden.
Ich denke auch alles falsch. Gibt es einen besseren Weg, dieses Szenario zu bewältigen?
Genau. Jetzt habe ich einen Prozess pro Nachricht implementiert, um das Routing durchzuführen. und dann einen Prozess pro Benutzer, um diese Nachrichten zu empfangen. und der gen_server führt das Laichen und die Buchhaltung von Benutzerprozessen durch. Nachdem ich Ets Optionen gemäß A. Sarid Antwort gesetzt habe, funktionierte die Lösung gut mit echtem Traffic. – Aus
Sie haben auch den Benutzer Prozess haben die Listenting, so dass kein Routing erforderlich ist. Dies ist in diesem Fall nicht möglich, da die Nachrichten vom selben RPC in Form von Datensätzen kommen. wäre fantastisch, wenn die Nachrichtenquelle einen Socket/PID pro Benutzer hat. – Aus