Datenbank synchronisieren

Themen zum Programmieren, Skripten, etc.

Moderator: LiMuBei

Benutzeravatar
LiMuBei
J:I Chief
Beiträge: 1415
Registriert: Sonntag 23. Januar 2005, 18:44
Wohnort: Karlsruhe
Kontaktdaten:

Beitrag von LiMuBei » Dienstag 21. November 2006, 16:42

Mein Gedanke war halt, dass man die Synchronisationsanfragen über den Chat-Kanal schickt. So nach dem Motto: "Ich habe Liste X mit Timestamp Y, hat jemand was neueres?" Falls jemand was neueres hat, postet er seinen Timestamp in den Chat. Der fragende such sich dann den mit dem neuesten Timestamp raus und fragt ihn per tell nach Aktualisierung, die der dann auch wieder per tell zurückschickt. Dadurch dass jeder seinen Timestamp in den Chat postet, sehen andere unter Umständen auch dass sie nicht mehr aktuell sind und können den neuesten nach Aktualisierung fragen.
Das würde meiner Meinung nach den Traffic reduzieren, weil eben nur noch kurze Anfragen über den Chat gehen und auch nur dann ne Liste verschickt wird wenn sie wirklich benötigt wird. Zusätzlich braucht man auch nur einen Timestamp pro Liste.
Ist jetzt nicht vollständig durchdacht, vielleicht gibt es gravierende Nachteile an dieser Idee...
Against logic there is no armor like ignorance.

Benutzeravatar
Behemoth
Initiative Big Boss
Beiträge: 1827
Registriert: Donnerstag 10. Februar 2005, 14:48
Wohnort: Karlsruhe

Beitrag von Behemoth » Dienstag 21. November 2006, 19:22

Problem wäre dann: du änderst lokal was an deiner Liste, und bekommst danach (in einer größeren Gilde) Dutzende von Anfragen, an die alle die gleichen Daten verschickt werden. Was Traffic zum Server angeht, ist das ja wesentlich schlechter, als Broadcast - ist ja kein Unterschied von meiner Seite aus, ob eine Nachricht im allgemeinen Channel oder im Whisper versendet wird.

Klar könnte man den Fall dann mit der alten Methode abfangen, aber hätte dann auch entsprechend zwei verschiedene Sync-Methoden, je nach dem, was sich ändert.
Look at me, I'm invisible!

Benutzeravatar
Behemoth
Initiative Big Boss
Beiträge: 1827
Registriert: Donnerstag 10. Februar 2005, 14:48
Wohnort: Karlsruhe

Beitrag von Behemoth » Samstag 25. November 2006, 18:19

Falls sich jemand den Code ankucken will, nur zu. *ZuSungiWink* :mrgreen:
Look at me, I'm invisible!

Benutzeravatar
Magic
WoW Dictionary
Beiträge: 1650
Registriert: Donnerstag 10. Februar 2005, 15:35
Wohnort: Tübingen

Beitrag von Magic » Dienstag 28. November 2006, 11:21

Hey, könntest du mir eine "Starthife" geben? Ich habe letztens mal geschaut, was für Dateien alles dazu gehören, und die kurz überflogen. Neben Code sind ja auch noch Spezifikationsdateien für z.B. frames dabei, wenn ich das richtig in Erinnerung habe. Wo fange ich am besten an zu gucken? Bei den events OnLoad und noch so eins?
:zauberer2: Ilyrielle - Mage

Benutzeravatar
Behemoth
Initiative Big Boss
Beiträge: 1827
Registriert: Donnerstag 10. Februar 2005, 14:48
Wohnort: Karlsruhe

Beitrag von Behemoth » Dienstag 28. November 2006, 23:54

GGTrader.lua ist alles wichtige drin eigentlich.
Look at me, I'm invisible!

Benutzeravatar
Magic
WoW Dictionary
Beiträge: 1650
Registriert: Donnerstag 10. Februar 2005, 15:35
Wohnort: Tübingen

Beitrag von Magic » Dienstag 5. Dezember 2006, 09:42

Noch eine Frage, wo der Verdopplungsfehler eigentlich auftritt. Da gibt es ja mehrere Möglichkeiten:
- beim Ersteller: Besitzer hat bereits doppelte Infos und verschickt diese.
- beim Empfänger: Verdopplung entsteht durch die Übertragung.
- bei der Anzeige: Daten sind überall korrekt gespeichert.

Es ist sicher, dass es sich um Fall 2 handelt, ja?
:zauberer2: Ilyrielle - Mage

Benutzeravatar
Behemoth
Initiative Big Boss
Beiträge: 1827
Registriert: Donnerstag 10. Februar 2005, 14:48
Wohnort: Karlsruhe

Beitrag von Behemoth » Dienstag 5. Dezember 2006, 19:23

Fall 1 wird sich natürlich verbreitern, also wenn jemand schon neuere falsche Daten hat, dann wird er die natürlich auch weiter geben. Anzeige müsste stimmen.

Ich sehe den Schwerpunkt bei Fall 2. Ich vermute, dass es zumindest zum Teil daran liegt, dass nicht alle die Items in der gleichen Reihenfolge haben (sind auf deutschem und englischen Client unterschiedlich sortiert). Wenn da dann irgendwas beim Synchronisieren dazwischen kommt, könnte das eine Ursache sein. Wobei das aber eher eine Erklärung dafür wäre, dass Gegenstände sich "verdoppeln" in dem sie andere "überschreiben". Aber das ist ja nicht der Fall (so weit ich weiß), sondern auch wenn man nur einen Gegenstand drin hat, hat man den irgendwann mehrmals drin.

Hm, mir ist gerade eine mögliche Fehlerquelle aufgefallen... nacher mal kucken.
Look at me, I'm invisible!

Benutzeravatar
Magic
WoW Dictionary
Beiträge: 1650
Registriert: Donnerstag 10. Februar 2005, 15:35
Wohnort: Tübingen

Beitrag von Magic » Mittwoch 6. Dezember 2006, 10:38

Was passiert eigentlich, wenn zwei Operationen zugleich angestoßen werden? Sollte zwar unwahrscheinlich sein, aber so prinzipiell taucht das Problem ja bei vielen Anwendungen auf. Z.B. wird die Liste gerade lokal sortiert, während eine Übertragung angestoßen wird.

Die Rekursionen in GGT_AddOffer() und GGT_AddNeed() würde ich übrigens auflösen. Sollte aber an sich auch keine Probleme machen, ok.
:zauberer2: Ilyrielle - Mage

Benutzeravatar
Magic
WoW Dictionary
Beiträge: 1650
Registriert: Donnerstag 10. Februar 2005, 15:35
Wohnort: Tübingen

Beitrag von Magic » Mittwoch 6. Dezember 2006, 10:55

Könnte es zu Unstimmigkeiten kommen, wenn man die Bank öffnet (mit Update-Modus an), dann /ggoffer verwendet und danach die Bank schließt? Wenn ich das richtig sehe, müsste dann /ggoffer verloren gehen.

Die Rekursion in GGT_UpdateSyncedOffers() ließe sich auch auflösen. :)
:zauberer2: Ilyrielle - Mage

Benutzeravatar
Magic
WoW Dictionary
Beiträge: 1650
Registriert: Donnerstag 10. Februar 2005, 15:35
Wohnort: Tübingen

Beitrag von Magic » Mittwoch 6. Dezember 2006, 11:27

GGT_ValidPlayers sind diejenigen Spieler, die sich per GGT_Send_DataVersion() bei mir registriert haben, gell? Wie wird sicher gestellt, dass das nur Gildies sind? (In einer anderen Datei, nehme ich an?) GGT_ValidPlayers werden nicht mehr entfernt, bis man selbst ausloggt, ja?

Sehe ich das richtig, dass Variablen zugleich als Array und Struct verwendet werden können? Also genau gesagt ist "[1]" wohl genau so ein Struct-Eintrag wie z.B. ".sorted", ja?
:zauberer2: Ilyrielle - Mage

Benutzeravatar
Magic
WoW Dictionary
Beiträge: 1650
Registriert: Donnerstag 10. Februar 2005, 15:35
Wohnort: Tübingen

Beitrag von Magic » Mittwoch 6. Dezember 2006, 14:18

So, bin wieder da, aber inzwischen wurde mein Rechner hier fertig installiert, also könnte ich auch wieder was arbeiten. :lol:

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
Was passiert eigentlich bei der for-Schleife

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
wenn 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})".

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?

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.

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.

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.

Zu guter Letzt: Fremden, unkommentierten Code durchzuschauen ist doppelt nervig, weißt ja. :-)
:zauberer2: Ilyrielle - Mage

Benutzeravatar
Behemoth
Initiative Big Boss
Beiträge: 1827
Registriert: Donnerstag 10. Februar 2005, 14:48
Wohnort: Karlsruhe

Beitrag von Behemoth » Mittwoch 6. Dezember 2006, 17:37

Ich werde mal richtig antworten, wenn ich wieder klar denken kann (krank ftw!).
Look at me, I'm invisible!

Benutzeravatar
Behemoth
Initiative Big Boss
Beiträge: 1827
Registriert: Donnerstag 10. Februar 2005, 14:48
Wohnort: Karlsruhe

Beitrag von Behemoth » Mittwoch 6. Dezember 2006, 17:39

Magic hat geschrieben:Könnte es zu Unstimmigkeiten kommen, wenn man die Bank öffnet (mit Update-Modus an), dann /ggoffer verwendet und danach die Bank schließt? Wenn ich das richtig sehe, müsste dann /ggoffer verloren gehen.

Die Rekursion in GGT_UpdateSyncedOffers() ließe sich auch auflösen. :)
Im Moment werden alle von Hand erstellten Offers beim automatischen Syncen gelöscht, weil ich mir noch nicht die Mühe machen wollte, die irgendwie anders zu verwalten.
Look at me, I'm invisible!

Benutzeravatar
Behemoth
Initiative Big Boss
Beiträge: 1827
Registriert: Donnerstag 10. Februar 2005, 14:48
Wohnort: Karlsruhe

Beitrag von Behemoth » Mittwoch 6. Dezember 2006, 17:43

Magic hat geschrieben:GGT_ValidPlayers sind diejenigen Spieler, die sich per GGT_Send_DataVersion() bei mir registriert haben, gell? Wie wird sicher gestellt, dass das nur Gildies sind? (In einer anderen Datei, nehme ich an?) GGT_ValidPlayers werden nicht mehr entfernt, bis man selbst ausloggt, ja?

Sehe ich das richtig, dass Variablen zugleich als Array und Struct verwendet werden können? Also genau gesagt ist "[1]" wohl genau so ein Struct-Eintrag wie z.B. ".sorted", ja?
Es können nur Leute in der gleichen Gilde über den Gilden-Addon-Channel senden. Wird erst beim ausloggen oder UI-Reload gelöscht, ja.

Es gibt keine Structs, es gibt nur assoziative Arrays. Ausserdem noch ein paar Convenience-Schreibweisen: data.sorted ist das gleiche wie data["sorted"]. Funktionen zum Iterieren durch das Array (wie z.B. getn) beziehen sich nur auf die Elemente, die eine natürliche Zahl, von 1 beginnend und dann aufsteigend als key haben.
Look at me, I'm invisible!

Benutzeravatar
Behemoth
Initiative Big Boss
Beiträge: 1827
Registriert: Donnerstag 10. Februar 2005, 14:48
Wohnort: Karlsruhe

Beitrag von Behemoth » Mittwoch 6. Dezember 2006, 17:45

So, den langen Post nehme ich mir aber erst später vor. :cry:
Look at me, I'm invisible!

Antworten