Datenbank synchronisieren
Moderator: LiMuBei
- Behemoth
- Initiative Big Boss
- Beiträge: 1827
- Registriert: Donnerstag 10. Februar 2005, 14:48
- Wohnort: Karlsruhe
Stimmt fast. Sollte aber "nur" einen Durchlauf ausmachen, wenn tatsächlich die anderen nichts voneinander wissen (sollte nicht vorkommen). Deine Variante würde aber nicht "nachfragen", wenn ein neuer neuerer Timestamp ankommt. Bei Dir hat die requesttime Prio vor dem Timestamp, und sollte genau anders rum sein. Bzw.: bei Deiner Version ist es nur von der Zeit abhängig, ob neu angefragt wird, und eigentlich gar nicht davon, ob die Daten überhaupt neuer sind als die eigenen.Magic hat geschrieben:GGT_Handle_PlayerTime() ...
Ok, ich empfange einen timestamp zu einem player, der neuer ist als meine eigene Info, timestamp > data.timestamp.
Ich fordere die Info an mit GGT_Send_PlayerTime(data) und erwarte die neue Info, data.desiredtimetamp (sp?) = timestamp.
Nun empfange ich den gleichen timestamp zum gleichen player von einem anderen sender.
Wegen not data.lastrequesttime fordere ich die Info nochmal an mit GGT_Send_PlayerTime(data), ja?
Nun empfange ich einen noch neueren timestamp zu dem player, timestamp > data.desiredtimestamp.
Dann fordere ich die Info gleich nochmal an, oder? ^^
Vielleicht besser so:Code: Alles auswählen
if not data.desiredtimetamp or data.desiredtimetamp < timestamp then data.desiredtimetamp = timestamp end if not data.lastrequesttime or data.lastrequesttime + GGT_AnswerDelay < time() then GGT_Send_PlayerTime(data) data.lastrequesttime = time() end
Ich habe es mal geändert zu:
Code: Alles auswählen
if not data.desiredtimestamp or data.desiredtimestamp < timestamp then
GGT_Send_PlayerTime(data)
data.desiredtimestamp = timestamp
data.lastrequesttime = time()
elseif not data.lastrequesttime or data.lastrequesttime + GGT_AnswerDelay < time() then
GGT_Send_PlayerTime(data)
data.lastrequesttime = time()
end
Look at me, I'm invisible!
- Behemoth
- Initiative Big Boss
- Beiträge: 1827
- Registriert: Donnerstag 10. Februar 2005, 14:48
- Wohnort: Karlsruhe
Stimmt genau. Man könnte i noch um eins decrementieren nach dem tremove, aber weiss gerade nicht, ob das in Lua mit Zählvariablen geht. Gleich mal testen.Magic hat geschrieben: Was passiert eigentlich bei der for-Schleifewenn tremove ausgeführt wird? Wird ein Eintrag übersprungen? Ist aber nicht schlimm, weil GGT_RequestHandler() eh wieder aufgerufen wird, gell? Wird es 1x pro Sekunde aufgerufen? In Bezug auf "tinsert(GG_UpdateFuncs, {delay = 1, func = GGT_RequestHandler})".Code: Alles auswählen
for i = 1, getn(GGT_RequestQueue) do if GGT_RequestQueue[i] and GGT_RequestQueue[i].sendtime <= curtime then GGT_Send_PlayerDataByName(GGT_RequestQueue[i].name) tremove(GGT_RequestQueue, i) end end
Look at me, I'm invisible!
- Behemoth
- Initiative Big Boss
- Beiträge: 1827
- Registriert: Donnerstag 10. Februar 2005, 14:48
- Wohnort: Karlsruhe
Müssten es gewesen sein. Nachvollziehen kann ich es jetzt nicht mehr, weil setn mit 2.0.1 rausgeflogen ist, aber ich habe es mit einer Funktion ersetzt, die nil reinschreibt in die unbelegten, jo.Magic hat geschrieben:GGT_Handle_Item arbeitet ja direkt in der aktuellen Liste. Na wenn das mal gut geht.
Was passiert, wenn nur eine Nachricht empfangen wurde und dann die Verbindung abbricht?
table.setn(items, totalitems) setzt die Listengröße auf das Soll, ohne dass alle Einträge vorhanden sind. Sind das dann leere Einträge?
Durch das Setzen und die Überprüfung in GGT_CheckForSyncEnd wird der Timestamp der Liste auf den "minimalen" Timestamp aller darin steckenden Items gesetzt. Beim Übertragen werden die Timestamps der Items alle auf den der Liste "reduziert". Potentielle Fehlerquelle, da hast Recht.Magic hat geschrieben:Deine items haben eigene timestamps. Diese sind gleich dem timestamp der Liste, wenn alles gut ging. Zu Inkonsistenzen kommt es während der Übertragung/Aktualisierung. Was geschieht, wenn die Inkonsistenz nicht aufgelöst wird? In GGT_Send_PlayerData() setzt du die item-timestamps auf die der Liste, falls es Abweichungen gab, ohne darauf einzugehen. Absicht? Falls ich eine unvollständige Liste empfangen hatte und mir derzeit niemand eine aktuellere geben kann - jetzt kommt eine Anfrage auf meine Liste - ist das der Zeitpunkt, an dem meine Liste zu einer gültigen Liste gemacht wird? Was passiert eigentlich bei der Übertragung einer unvollständigen Liste? Es wird getn(data.offers) betrachtet, aber die einzelnen items werden nicht mehr geprüft.
Von der Art war mein erster Ansatz, und der führte immer dazu, dass Leute aus der Anzeige verschwanden (Liste wurde gelöscht, aber dann kam nichts mehr, Liste = leer, Spieler verschwindet aus Anzeige). Doppelpufferung wäre wohl eine Möglichkeit, aber davor hatte ich immer Bammel, weil es ist ja immerhin "nur" eine Skriptsprache, und ich finde es jetzt schon ganz schön krass, wieviel Zeug da dann im Speicher rumfährt, wenn man "nur ein paar Items abspeichern will". Najo, vielleicht ist das auch gar kein wirklich Problem, und ich bilde mir das nur ein, mal kucken.Magic hat geschrieben:Wie gesagt hätte ich die Übertragung der Listen etwas anders gestaltet. Sicherer erscheint es mir, die übertragene Listen erst zu puffern und nur bei Vollständigkeit die alten zu ersetzen. Oder: Man kann es auch so sehen, dass wenn es eine neue Liste gibt, dann kann ich die alte eh verwerfen (wohl nur bei Needs sinnvoll). Also statt einzelne Einträge überschreiben, erst mal alte Liste komplett weg, dann auffüllen. Sollte ich unvollständige Liste haben und jemand will diese haben, so hat er zum Schluss auch nur eine als unvollständig markierte Liste.
Gleiches Problem wie oben: benötigt halt ganze Menge Speicher/Rechenzeit. Aber klingt so, als wäre eine genauere Betrachtung des Ansatzes eine ganz gute Idee.Magic hat geschrieben:Noch eine Idee, falls du in der bestehenden Liste aktualisieren willst: Sortiere die items stets sprachunabhängig nach ihrer ID. Alphabetische Anzeigelisten können nebenher erstellt/abgespeichert werden. Übertragen wird auch nach der ID sortiert. Wenn eine zweite ID empfangen wird, können alle bestehenden IDs zwischen erster und zweiter empfangener ID gelöscht werden. Dieses Vorgehen ist aber eigentlich nur zu empfehlen, wenn Listen oft nicht vollständig aktualisiert werden können.
Pah! Versuch mal Code durchzuschauen, bei dem die Hälfte des Codes in der cpp Datei, ein Viertel in der h Datei, der Rest in irgendwelchen ominösen inl Dateien steckt, und alles mit kyrillischen Kommentaren versehen ist! Dann weisst du, was doppelt nervig ist! Russland 4tw!Magic hat geschrieben:Zu guter Letzt: Fremden, unkommentierten Code durchzuschauen ist doppelt nervig, weißt ja.
Danke schon mal, für die vielen Ideen.
Look at me, I'm invisible!