Closed sterni24 closed 6 years ago
Soll ein OKF-Server mit vielen eingesammelten Daten dieselben Ergebnisse liefern können wie ein einzelner RIS-Server?
Die Frage (bzw. deren Anlass) verstehe ich nicht. Weshalb sollte es vom Betreiber abhängen, welche Daten sein Server liefern kann?
Die Idee dabei ist, dass die vom OKF-Server eingesammelten Daten via OParl-Schnittstelle abgefragt / ausgewertet werden können. Ähnliche Überlegungen für eine zentrale Datenhaltung gab es bereits im Jahr 2016 beim Land Rheinland-Pfalz.
Um für dieses Szenario die korrekte Ausgabe einer Tagesordnung zu gewährleisten, spielt die Sortierung der AgendaItem
s eine elementare Rolle.
Im Übrigen halte ich nichts davon, im Update-Mechanismus Ausnahmen in Form von eingebetteten Listen (LegislativTermin
, AgendaItem
) mangels fehlender Objekteigenschaften zu kreieren.
Vorweg: OParl 1.1 (und der Update-Mechasnismus im Allgemeinen) sind in keinster Weise nur für eine sammelnde Zentralinstanzen wie Politik bei Uns, sondern für alle Clients gedacht.
Wie kann ein Client, der seine Daten über den Update-Modus aktualisiert, bei Ausgabe seines Datenbestandes derzeit die Reihenfolge seiner Tagesordnung bestimmen? Muss er dabei selbst für eine korrekte Sortierung sorgen?
Ein Client bekommt die Reihenfolge der Tagesordnungspunkte durch die Reihenfolge der eingebetteten Objekte. Wie er diese speichert bleibt ihm überlassen, die meisten werden vermutlich einfach die Position als zusätzliche Spalte in ihrer Datenbank speichern.
Soll ein OKF-Server mit vielen eingesammelten Daten dieselben Ergebnisse liefern können wie ein einzelner RIS-Server?
Beide Server sollten prinzipiell die gleichen Daten ausgeben können.
Ist es überhaupt sinnvoll, auch im Hinblick auf die Aktualität, alle Objekte für den Update-Modus bereitzustellen? Wenn ja, warum wird hier bei LegislativTerm eine Ausnahme gemacht?
Ja, z.B. kann für eine App schnell den lokalen Datenbestand aktualisieren, um darauf dann eine eigene Suche oder eine Offline-Funktion anzubieten.
Bei LegislativTerm
war der Gedanke, dass die Liste ja schon in Body exisitiert und es sich daher nicht lohnt, dazu noch eine externe Liste anzubieten. Es wäre aber kein Problem, auch für LegislativTerm
noch eine externe Liste hinzuzufügen.
Ich bin der Meinung, die Version Oparl 1.1 nicht als schnelle Lösung für den Abgleich bei https://politik-bei-uns.de/ zu veröffentlichen, sondern diese Fragen (und vielleicht noch andere) im Hinblick auf zukünftige Versionen nachhaltig zu klären.
Die nachhaltigere (und deutlich einfachere) Lösung wäre es, die internen Listen durch URL-Listen ersetzen. Diese Ausgabe könnten OParl-1.0-Clients aber nicht mehr verstehen und OParl-Server müssten zu großen Teilen neu geschrieben werden, was wir vermeiden wollten. In OParl 1.1 versuchen wir daher, die in OParl 1.0 fehlenden Funktionen ohne Kompatibilitätsbruch nachzurüsten.
Um für dieses Szenario die korrekte Ausgabe einer Tagesordnung zu gewährleisten, spielt die Sortierung der AgendaItems eine elementare Rolle.
Im Übrigen halte ich nichts davon, im Update-Mechanismus Ausnahmen in Form von eingebetteten Listen (LegislativTermin, AgendaItem) mangels fehlender Objekteigenschaften zu kreieren.
Bei LegislativeTerm
würde wie oben beschrieben eine zusätzliche externe Liste in Body
ausreichen. für AgendaItem
wäre eine agendaItemOrder
wie von @Medo42 in https://github.com/OParl/spec/pull/397#issuecomment-372151093 beschrieben nötig.
korrekte Ausgabe einer Tagesordnung
Diese Anforderung betrifft auch andere Proxy-Server und ist auch unabhängig von dem Datenformat, welches die Server liefern. Ich selbst lege z.B. auch bei einer Ausgabe als Linked Data viel Wert auf die korrekte Reihenfolge der TOPs.
die internen Listen durch URL-Listen ersetzen. [...] OParl-Server müssten [dann aber] zu großen Teilen neu geschrieben werden
Auch wenn ich nicht sehr optimistisch bezüglich der Code-Qualität bin: Diese Bewertung des Aufwands halte ich für gewagt.
Es geht mir nicht darum, interne Listen durch URL-Listen zu ersetzen. Es geht darum, für den Update-Modus einen sauberen, generischen Ansatz zu finden, mit dem alle Objekte zeitsparend und ohne großen Aufwand aktualisiert werden können. Hierzu werden interne Listen nicht benötigt.
Bei LegislativeTerm würde wie oben beschrieben eine zusätzliche externe Liste in Body ausreichen. für AgendaItem wäre eine agendaItemOrder wie von @Medo42 in #397 (comment) beschrieben nötig.
Wird das nun so umgesetzt?
Wird das nun so umgesetzt?
Der Kommentar war (ebenso wie das Pull Request #397) als Vorschlag zur Diskussion gedacht. Wenn die Frage als Zustimmung zu agendaItemOrder
gemeint ist, werde ich das gerne dem Pull Request hinzufügen.
Die Bezeichnung der Eigenschaft würde ich noch ändern in order
oder numberOrder
.
Die Bezeichnung der Eigenschaft würde ich noch ändern in
order
odernumberOrder
.
Dem Namen nach würde das eher zu einer numerischen Eigenschaft an AgendaItem passen. Reden wir hier noch über das selbe?
Wir reden über den fehlenden Sortierschlüssel in AgendaItem
. M. E. reicht hier ein numerischer Wert von 1 bis n aus.
Das ist allerdings ein gänzlich anderer Vorschlag als das, was bisher unter dem Namen agendaItemOrder
diskutiert wurde (das war eine Eigenschaft im Meeting-Objekt, die die IDs der AgendaItems in der entsprechenden Reihenfolge enthält). Und ich bekomme gerade das erste mal mit, dass "Sortierschlüssel in AgendaItem" als Lösungsvorschlag überhaupt im Raum steht.
Mit dieser Alternative könnte ich auch arbeiten, aber eine laufende Nummer ist m.E. etwas spezifischer als nötig wenn es nur darum geht eine Reihenfolge festzulegen. Das führt dazu, dass sich bei Hinzukommen eines AgendaItems in der Mitte der Liste alle nachfolgenden AgendaItems ebenfalls ändern müssen (d.h. sie müssen auch synchronisiert werden), da sich ihre laufende Nummer erhöhen muss.
Sorry, das mit der Eigenschaft in Meeting
hab ich wohl überlesen. Noch einmal zum Update-Modus:
In der von @konstin beschriebenen Version und Ihrem Vorschlag muss der Client im Update-Modus zunächst alle AgendItem
-Objekte des Meeting
s entfernen und die neuen gemäß interner Liste oder der agendaItemOrder
(deren Objekte dann nachgelesen werden müssen) neu hinzufügen. Das kann es nicht sein, zumal, wenn sich nur ein AgendaItem
ändert, immer das dazugehörige Meeting
-Objekt (obwohl sich dieses vielleicht gar nicht geändert hat) mit allen AgendaItems
erneut ausgegeben werden muss.
Von der Laufzeit dürfte das keine große Rolle spielen, aber aus Entwicklersicht, sowohl server- als auch clientseitig, ist diese Lösung nicht zu empfehlen. Ich plädiere für die bereits weiter oben von mir beschriebene Lösung.
@Medo42, es wäre schön, wenn Sie sich in diesem Forum bekannt machen würden.
agendaItemOrder
sollte der Einfachheit halber immer mit Meeting
ausgegeben werden sollte, auch wenn dadurch etwas Redundanz entsteht.
Wenn sich ein Tagesordnungspunkt ändert, z.B. weil sich sein Titel geändert hat, müsste bei beiden Vorschlägen nur der Tagesordnungspunkt vom Client neu heruntergeladen werden.
Wenn ein Tagesordnungspunkt in hinzukommt oder gelöscht wird, müsste mit agendaItemOrder
nur das Meeting
und das betroffene AgendaItem
aktualisiert werden. Mit order
in Meeting
hingegen würden sich alle Tagesordnungspunkte nach dem neuen bzw. gelöschten ändern, das sich order
ändert. Bei den mir bekannten langen Tagesordnungen würde mit order
in Meeting
die Menge der für eine Aktualisierung übertragen Daten und Objekten deutlich größer sein als mit agendaItemOrder
.
Nach meiner Erfahrung wären beide Vorschläge etwa dem gleichen recht geringen Aufwand implementierbar (sowohl mit Yii in PHP als auch mit django in Python wären es < 10 Zeilen Code). Auf Grund meiner Erwartungen zur Laufzeit favorisiere ich agendaItemOrder
.
Im Interesse der Transparenz: Mein Name ist Simeon Maxein, und ich entwickle als Angestellter der Chamaeleon AG einen OParl-Client. Ich diskutiere hier allerdings im Moment nicht "im Auftrag der Firma" sondern habe mich eher dazu verleiten lassen Vorschläge zu schreiben, wenn ich beim Lesen eine Idee hatte von der die Spezifikation mMn profitieren würde. Eigentlich wollte ich mich gar nicht so weit "einklinken", aber so kann es kommen ;)
Ich sehe nicht, dass man bei einer Änderung der Reihenfolge in agendaItemOrder
alle AgendaItems des Meetings neu abfragen müsste. Der Client hat diese AgendaItems doch bereits in seinem lokalen Datenbestand vorliegen und muss lediglich deren Reihenfolge aktualisieren. Egal ob der Client diese Reihenfolge nun intern als laufende Nummer ausdrückt oder ob er seinerseits eine sortierte Liste o.ä. verwendet - diese Aktualisierung dürfte trivial sein.
Für den Server kann es eigentlich auch nicht schwierig sein agendaItemOrder
auszugeben, da er ja bereits für die Eigenschaft agendaItems
eine sortierte Liste der AgendaItems ausgeben kann. Für agendaItemOrder
muss er diese Ausgabe lediglich auf die IDs beschränken.
@Medo42 Danke für Ihre Nachricht.
Ich sehe nicht, dass man bei einer Änderung der Reihenfolge in
agendaItemOrder
alle AgendaItems des Meetings neu abfragen müsste.
Mit der Ausgabe der agendaItemOrder
im Update-Modus haben Sie nur die Möglichkeit, die Reihenfolge der Objekte mit dem lokalen System abzustimmen. Allerdings ändert sich in aller Regel mit der Reihenfolge auch die Eigenschaft number
. Darüber hinaus haben Sie keinen Anhaltspunkt, ob sich sonst irgendetwas geändert hat.
zu den Punkten von @konstin:
Wenn sich ein Tagesordnungspunkt ändert, z.B. weil sich sein Titel geändert hat, müsste bei beiden Vorschlägen nur der Tagesordnungspunkt vom Client neu heruntergeladen werden.
Woher weiß der Client, welcher der Tagesordnungspunkte sich geändert hat? Oder wollen Sie im Update-Modus nur die hinzugefügten, geänderten und gelöschten IDs in agendaItemOrder
bereitstellen?
Wenn ein Tagesordnungspunkt hinzukommt oder gelöscht wird, müsste mit
agendaItemOrder
nur das Meeting und das betroffeneAgendaItem
aktualisiert werden.
das kann so gar nicht sein, siehe Ausführung zur Eigenschaft number
weiter oben.
Für den Server kann es eigentlich auch nicht schwierig sein agendaItemOrder auszugeben, da er ja bereits für die Eigenschaft agendaItems eine sortierte Liste der AgendaItems ausgeben kann. Für agendaItemOrder muss er diese Ausgabe lediglich auf die IDs beschränken.
Von der Laufzeit dürfte das keine große Rolle spielen, aber aus Entwicklersicht, sowohl server- als auch clientseitig, ist diese Lösung nicht zu empfehlen.
Bei der unmittelbaren Abfrage der AgendaItem
s im Update-Modus braucht es überhaupt keine Sonderbehandlung, außer der Aufnahme der neuen Eigenschaft order
.
Allerdings ändert sich in aller Regel mit der Reihenfolge auch die Eigenschaft number.
Das verringert in der Tat den Vorteil der agendaItemOrder
-Lösung. Die Nummerierung von AgendaItems ist allerdings oft strukturiert, so dass beim Einfügen eines Unterpunkts eventuell nur bei wenigen folgenden AgendaItems die number
-Eigenschaft geändert werden muss. Wie groß der Unterschied zwischen den beiden Mechanismen in der Realität wäre kann man vermutlich nur durch eine Analyse echter Änderungen in einem bestehenden System herausfinden, und ich glaube diesen Aufwand will hier niemand betreiben.
Woher weiß der Client, welcher der Tagesordnungspunkte sich geändert hat?
Genau wie bei allen anderen Objekttypen - daher, dass geänderte AgendaItems in der entsprechenden Objektliste am Body-Objekt bereitgestellt werden.
Ich denke, wir haben die wichtigsten Punkte zu beiden Ansätzen besprochen. Wie oben schon erwähnt finde ich beide Lösungen akzeptabel und verzichte daher auf weitere Argumente zu meiner Präferenz.
Wahrscheinlich wird der Unterschied mit einem Beispiel klarer.
Es gebe Listen für AgendaItem
und Meeting
:
https://oparl.example.org/body/0/list/agendaitem
https://oparl.example.org/body/0/list/meeting
Weiterhin gebe es einen Termin mit 50 Tagesordnungspunkten, den wir im Folgenden betrachten.
Beim ersten Abruf am 1.1.2000 lädt der Client entweder die Seiten Terminliste herunter oder die Terminliste mit omit_internal
und dazu die Liste der Tagesordnungspunkte. Er speichert alle Objekte in einer lokalen Datenbank.
Nach den ersten Abruf des Client wird ein einzelner TOP in die Mitte der Tagesordnung des Termins hinzugefügt. (Der Fall, bei dem ein TOP gelöscht wird, verläuft analog.)
Der Client will nun am 2.1.2000 seinen Datenbestand mit omit_internal
aktualisieren. In beiden Fällen lädt er dabei die Terminliste und die Liste der TOP mit omit_internal
und dem passenden Wert für modified_since
herunter.
https://oparl.example.org/body/0/list/agendaitem?omit_internal=True?modified_since=2000-01-02T00%3A12%3A00%2B01%3A00
https://oparl.example.org/body/0/list/meeting?omit_internal=True?modified_since=2000-01-02T00%3A12%3A00%2B01%3A00
order
Der Termin ist unverändert, d.h. die zurückgegebene Terminliste ist leer.
Bei der Liste der TOP ist der eingefügte TOP geändert, da er neu erstellt wurde. Außerdem hat sich bei den 25 TOP dahinter order
um 1 erhöht, diese sind also auch geändert.
Es werden also insgesamt 26 Objekte übertragen.
agendaItemOrder
In dem Termin hat sich das Feld agendaItemOrder
geändert, es ist also ein Eintrag in der Terminliste.
Bei der List der TOP ist wieder der eingefügte TOP neu. Alle anderen TOP haben sich nicht geändert.
Es werden also insgesamt 2 Objekte übertragen. Sollte sich durch den eingefügten TOP number
von dahinterliegenden TOP verändern, kann die Zahl auch höher sein, jedoch nie höher als die 27, d.h. die Zahl aus Fall 1 plus den Termin.
Ich favorisiere Fall 2, da gemittelt deutlich weniger Objekte übertragen werden.
@konstin Wie sieht der Inhalt Ihrer Eigenschaft agendaItemOrder
aus? Woher weiß der abrufende Client, an welcher Position sich dieser eine (neue) Top befindet?
@konstin schrieb:
Außerdem hat sich bei den 25 TOP dahinter order um 1 erhöht, diese sind also auch geändert.
In Programmiersprachen wie Basic
war es früher üblich, dass am Anfang jeder Zeile eine Zeilennummer angegeben werden musste. Damit nicht beim Einfügen einer Zeile immer in allen Folgezeilen die Zeilennummern geändert werden mussten gab es eine simple Konvention: Es wurde generell in Zehnerschritten nummeriert (https://de.wikipedia.org/wiki/BASIC#Programmierbeispiel). Dann konnte z.B. zwischen den unmittelbar aufeinander folgenden Zeilen 50 und 60 eine Zeile 55 eingefügt werden.
agendaItemOrder
könnte z.B. wie folgt aussehen:
Beim ersten Abruf:
{
"id": "https://oparl.example.org/body/0/meeting/0",
"type": "https://spec.oparl.org/1.1/Meeting",
"agendaItemOrder": [
"https://oparl.example.org/body/0/agendaitem/0",
"https://oparl.example.org/body/0/agendaitem/1",
...
"https://oparl.example.org/body/0/agendaitem/23",
"https://oparl.example.org/body/0/agendaitem/24",
"https://oparl.example.org/body/0/agendaitem/25",
...
"https://oparl.example.org/body/0/agendaitem/48",
"https://oparl.example.org/body/0/agendaitem/49"
],
...
}
Beim zweiten Abruf:
{
"id": "https://oparl.example.org/body/0/meeting/0",
"type": "https://spec.oparl.org/1.1/Meeting",
"agendaItemOrder": [
"https://oparl.example.org/body/0/agendaitem/0",
"https://oparl.example.org/body/0/agendaitem/1",
...
"https://oparl.example.org/body/0/agendaitem/23",
"https://oparl.example.org/body/0/agendaitem/24",
// Der neue TOP
"https://oparl.example.org/body/0/agendaitem/50",
"https://oparl.example.org/body/0/agendaitem/25",
...
"https://oparl.example.org/body/0/agendaitem/48",
"https://oparl.example.org/body/0/agendaitem/49"
],
...
}
@akuckartz Das wäre tatsächlich eine Möglichkeit, ist aber schwierig zu Debuggen und setzt voraus, dass das RIS die Position zusätzlich mit Intervall speichert.
@akuckartz Netter Versuch, dann liefern Sie mal gleich eine Routine zum neu durchnummerieren mit! :sunglasses:
Auch wenn wir hier mit 1000er oder besser 1024er Schritten arbeiten, lässt sich das Problem nicht zu 100% lösen. Da der Server in @konstin's Beispiel im agentaItem
keine order
liefert, kann der Client es nicht einsortieren.
Nun hat @konstin in seinem Beispiel doch den vollen Satz an Tagesordnungspunkten geliefert. Was soll der Client nun damit machen?
Irgendwie hatte ich schon befürchtet, dass mein Kommentar als Unterstützung für Alternative 1 verstanden werden könnte :smiley: Das ist aber nicht der Fall. Es gibt ja auch gute Gründe, warum man in Programmen heutzutage keine Zeilennummern mehr angeben muss. Aber auch Alternative 2 gefällt mir aufgrund der Redundanzen nicht.
Leider kann ich aktuell keinen konkreten Alternativ-Vorschlag liefern, der auch mir gefallen würde (Material als Grundlage für eine allgemeine Lösung sammele ich hier: https://github.com/OpenGovLD/specs/wiki/Replication)
Nun hat @konstin in seinem Beispiel doch den vollen Satz an Tagesordnungspunkten geliefert. Was soll der Client nun damit machen?
Der Client hat über die Liste der TOP die aktuelle Menge an TOP.
Nun kann er für alle geänderten Termine zum einen agendaItemOrder
direkt mit dem Termin speichern, um beim Anzeigen des Termins die zugehörigen TOP aus seiner Datenbank abzurufen und dann in der Reihenfolge von agendaItemOrder
anzuzeigen.
Er kann aber auch selbst einen Wert mit der gleichen Bedeutung wie order
zu jedem TOP speichern. Der Vorteil gegenüber dem Vorschlag mit order
liegt hier darin, dass agendaItemOrder
als Liste von urls deutlich kompakter ist als die TOP in einer externen Objektliste, die ggf. durch die Paginierung auch noch mehrere http-Abfragen braucht.
In Python könnte man das ganze z.B. wie folgt aussehen:
for modified_agenda_item in get_agenda_items(omit_internal=True, modified_since="2000-01-02T00:12:00+01:00"):
agenda_item = get_or_create_agenda_item_from_db(modified_agenda_item["id"])
agenda_item.update(modified_agenda_item)
agenda_item.save()
for modified_meeting in get_meetings(omit_internal=True, modified_since="2000-01-02T00:12:00+01:00"):
meeting = get_or_create_meeting_from_db(modified_meeting ["id"])
meeting.update(oparl_meeting)
meeting.save()
for order, id in enumerate(oparl_meeting["agendaItemOrder"]):
agenda_item = get_agenda_item_by_oparl_id(id)
agenda_item.order = order
agenda_item.save()
Wenn ich den Code von @konstin richtig interpretiere, werden in der ersten for-Schleife genau die agentaItem
s aktualisiert, die sich verändert haben. Hierbei rufen sie dieselbe externe Objektliste ab, die ggf. durch die Paginierung noch mehrere http-Abfragen braucht.
In meinem Ansatz unterstelle ich, dass jeder RIS-Hersteller für die Tagesordnung eine Sortierung (1-n oder 10, 20, 30 ...) vorhält. Unter der Voraussetzung, dass die Eigenschaft order
im AgendaItem
-Objekt mit zwingend beschrieben ist und vor dem ersten Update-Lauf eine Vollaktualisierung stattgefunden hat, wäre mein Vorschlag für den Update-Mechanismus damit voll umgesetzt.
Gestatten Sie mir zu der zweiten for-Schleife ein paar Anmerkungen:
AgendaItem
s, deren Termine sich nicht geändert haben, die Meeting
-Objekte bereitstellen, obwohl dieses nicht in der modified-since
-Liste enthalten ist.agendaItemOrder
eine zusätzliche Liste füllen, auch wenn gar keine AgendaItem
s geändert wurden. Ggf. kann diese Liste dann entfallen.omit_internal
zu ziehen, wäre dahin, weil sich der Server damit beschäftigt seine agendaItemOrder
zu füllen. Da ich davon ausgehe, dass nicht nur wir die OParl-Version 1.1. unterstützen werden, wäre es schön, wenn sich in dieser Sache der eine oder andere RIS-Hersteller zu Wort meldet.
wäre es schön, wenn sich in dieser Sache der eine oder andere RIS-Hersteller zu Wort meldet.
Ich bestätige die von @sterni24 genannten Punkte . Mit dem Verändern der Tagesordnung ändern sich die Nummer der nachfolgenden Punkte. Klar gibt es auch hierarchische Tagesordnungen, die meisten Kunden arbeiten jedoch ohne Unternummerierung.
Ebenso die Punkte 1.-3. des letzten Beitrags.
Ohne Unternummerierung fällt der Performace-Vorteil von agendaItemOder
weg. Ich habe daher die Variante mit order
in 788156ef22ffe148c74ba3e25467d44d0d25e465 implementiert und dazu in 98851fb92005689c920744992db903536a74cff3 den Sonderfall mit legislativeTerm in Body besseitigt. Damit sollte #397 vollständig sein.
Zur Diskussion um den Pull request #397 bleiben einige Fragen offen:
Wie kann ein Client, der seine Daten über den Update-Modus aktualisiert, bei Ausgabe seines Datenbestandes derzeit die Reihenfolge seiner Tagesordnung bestimmen? Muss er dabei selbst für eine korrekte Sortierung sorgen?
Soll ein OKF-Server mit vielen eingesammelten Daten dieselben Ergebnisse liefern können wie ein einzelner RIS-Server?
Ist es überhaupt sinnvoll, auch im Hinblick auf die Aktualität, alle Objekte für den Update-Modus bereitzustellen? Wenn ja, warum wird hier bei
LegislativTerm
eine Ausnahme gemacht?Ich bin der Meinung, die Version Oparl 1.1 nicht als schnelle Lösung für den Abgleich bei https://politik-bei-uns.de/ zu veröffentlichen, sondern diese Fragen (und vielleicht noch andere) im Hinblick auf zukünftige Versionen nachhaltig zu klären.