Laden...

Entwurfsmuster für mehrere/viele periodisch zu aktualisierende Anzeigen

Erstellt von tabstop vor 9 Jahren Letzter Beitrag vor 9 Jahren 2.432 Views
T
tabstop Themenstarter:in
94 Beiträge seit 2007
vor 9 Jahren
Entwurfsmuster für mehrere/viele periodisch zu aktualisierende Anzeigen

Es soll folgende Anwendung erstellt werden: Ein Lager besteht aus mehreren Regalen, die in Reihen strukturiert sind. Für jede Reihe soll ein Anzeigesystem aufgestellt werden, wo bestimmte Informationen der Lagerreihe (z.B. Anzahl freie Stellplätze) dargestellt werden. Diese Informationen sollen stetig aktualisiert werden (z.B. periodisch jede Minute). Es gibt beispielsweise 40 Anzeigesysteme.

Die Ansteuerung einer Anzeige sähe im Prinzip so aus: Ermittle Information für Anzeige -> stelle Information auf Anzeige dar -> warte eine Minute -> Ermittle Information für Anzeige …

Ich suche jetzt noch nach einem geeigneten bzw. praktischen Entwurfsmuster für die Ansteuerung aller Anzeigen. Ein erster Gedanke war, für jede Anzeige ein Instanz zu erzeugen, welches einen eigenen Timer besitzt, der dann jede Minute entsprechende Aufgaben bewältigt. So ganz bin ich von dieser Implementation jedoch noch nicht überzeugt. Wenn man ins Extreme gehen würde und man hätte z.B. 1000 Anzeigen hätte man ja auch 1000 Timer. Wie würdet ihr das umsetzen?

Jede Anzeige besitzt eine IP-Adresse und wird mittels TCP angesteuert (Socket, TcpClient), das ist aber nicht Teil der Fragestellung.

T
314 Beiträge seit 2013
vor 9 Jahren

Häng eben z.B. eine Ebene drüber. Ein Lager hat 1000 Stellplätze. Das Lager hat entsprechend den Timer.

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo tabstop,

ich versuche es mal mit einem Vergleich. Bei einem Strategiespiel muss jede Einheit auch in festen Abständen aktualisiert werden. Deshalb hat die einzelne Einheit aber keinen eigenen Timer, sondern es wird durch die Spiellogik (Controller) ein Takt von außen vorgegeben. Das würde ich auch in deinem Fall empfehlen und ich wüsste kein objektorientiertes Prinzip, gegen das man damit verstoßen würde. Die Anzeigen könnten weiter als Objekte gekapselt sein, nur der Anstoß kommt von außen. Es ist ohnehin der Normalfall, dass der Anstoß für die Verarbeitung in einem Objekt von außen kommt.

Ob die "Ebene drüber" nun eher inhaltlich ein Lager-Objekt sein muss oder ob es etwas technischer ein Controller-Objekt sein sollte oder ob es das Main-Programm sein könnte, sei dahingestellt.

Wenn es zuviel Last erzeugen würde, wenn alle Anzeigen (quasi) gleichzeitig aktualisiert werden würden, kann der Controller für seine Timer auch kürzeres Intervall verwenden, und dann bei jedem Tick nur einen entsprechenden Bruchteil der Anzeigen aktualisieren.

herbivore

M
171 Beiträge seit 2012
vor 9 Jahren

Wie werden denn die Daten der einzelnen Anzeigen ermittelt?
Wenn Du da die Möglichkeit hast, das eventgesteuert zu machen, wäre das sogar noch besser, dann brauchst Du garkeinen Timer, sondern jede Anzeige registriert sich auf Änderungen an seinem Datenobjekt.

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo tabstop,

in der Tat wäre eine Steuerung, die auf einem Benachrichtigungsmechanismus basiert, besser alles ein zeitgesteuertes Polling. Diesen Aspekt hatte ich in meiner ersten Antwort übersehen.

herbivore

P
1.090 Beiträge seit 2011
vor 9 Jahren

Hi ich wäre jetzt bei der Beschreibung davon ausgegangen, das es sich bei den Anzeigen um wirklich physikalisch Vorhandene Anzeigen handelt. Auf denen eine Software läuft, dann könnten die Anzeigen sich bei bedarf selber Updaten, die Daten könnte man dann über einen Service bereitstellen.

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

4.221 Beiträge seit 2005
vor 9 Jahren

in der Tat wäre eine Steuerung, die auf einem Benachrichtigungsmechanismus basiert, besser alles ein zeitgesteuertes Polling. Diesen Aspekt hatte ich in meiner ersten Antwort übersehen.

@herbivore

Allenfalls je nach Frequenz der Anpassungen wäre auch eine Kombination aus Event und Polling möglich.

--> Event setzt nur ein Flag dass sich irgendwelche Daten verändert haben
--> Timer holt dann die neue Darstellung

Dies hätte den Vorteil, dass häufige Anpassungen nicht zu allzu heftiger Auslastung führt und das Update besser geplant werden kann.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

T
tabstop Themenstarter:in
94 Beiträge seit 2007
vor 9 Jahren

Vielen Dank für die rege Teilnahme und konstruktiven Antworten.

Hi ich wäre jetzt bei der Beschreibung davon ausgegangen, das es sich bei den Anzeigen um wirklich physikalisch Vorhandene Anzeigen handelt. Auf denen eine Software läuft, dann könnten die Anzeigen sich bei bedarf selber Updaten, die Daten könnte man dann über einen Service bereitstellen.

Die Anzeige ist eine echte physikalische Einheit (7-Segment Anzeige mit mehreren Ziffern und zwei oder drei Reihen). Die selber ist unveränderlich insofern kann man dort auch keine eigene Software einspielen.

Wie werden denn die Daten der einzelnen Anzeigen ermittelt?

Die Daten kommen aus einer SQL Datenbank. Wir rechnen mit ca. 500000 Datenbewegungen pro Tag. Eine eventgesteuerte Verarbeitung schließe ich im Moment aus. Nicht jede Bewegung soll auch tatsächlich zu einer Aktualisierung der Anzeige führen.

ich versuche es mal mit einem Vergleich. Bei einem Strategiespiel muss jede Einheit auch in festen Abständen aktualisiert werden. Deshalb hat die einzelne Einheit aber keinen eigenen Timer, sondern es wird durch die Spiellogik (Controller) ein Takt von außen vorgegeben. Das würde ich auch in deinem Fall empfehlen und ich wüsste kein objektorientiertes Prinzip, gegen das man damit verstoßen würde. Die Anzeigen könnten weiter als Objekte gekapselt sein, nur der Anstoß kommt von außen. Es ist ohnehin der Normalfall, dass der Anstoß für die Verarbeitung in einem Objekt von außen kommt.

Also wird es wohl so etwas wie einen Controller geben, der für die Informationsbeschaffung und Fütterung der Anzeigen zuständig ist. Das sehe ich inzwischen genauso. Dann muss ich mir Gedanken machen zur Implementation des Controllers.

Vielen Dank erst mal.

M
171 Beiträge seit 2012
vor 9 Jahren

Die Daten kommen aus einer SQL Datenbank. Wir rechnen mit ca. 500000 Datenbewegungen pro Tag. Eine eventgesteuerte Verarbeitung schließe ich im Moment aus. Nicht jede Bewegung soll auch tatsächlich zu einer Aktualisierung der Anzeige führen.

Dann wäre aber der Hinweis von Programmierhans eigentlich optimal. Setze in deiner SQL-Datenbank einen Trigger ein, der Dir meldet, wenn sich ein Wert geändert hat. In deinem Polling kannst Du dann periodisch prüfen, ob der Trigger angekommen ist, und nur dann neu abfragen, wenn dem so ist.

16.834 Beiträge seit 2008
vor 9 Jahren

500.000 pro Tag ist nichts. Wenn wir von pro Sekunde reden würden wäre das ein anderes Level.

Ich würde einen Service vorschalten.
Die Clients verbinden sich mit diesem und nicht direkt mit der Datenbank. So kannst Du Benachrichtigungen viel viel einfacher implementieren.

Falls es dann Performance-Bedarf bezüglich der Skalierung geben würde ist das auchs kein Problem.
Dafür gibt es bereits empfehlenswerte Umsetzungen.

1.361 Beiträge seit 2007
vor 9 Jahren

Hallo,

Wir reden von grob einer Datenbankabfrage pro Minute und dem anschließenden Senden von 40 TCP Paketen an ein paar Digitalanzeigen.
Und schon fallen Begriffe wie "Last", "Performance"... Premature Optimization?!?! 😉

Da kann man auch ne einzeilige command-pipeline aus nem sql-tool, xargs und netcat im cron-file hinterlegen, fertig 😉

Zum Pogramm:* Ich würde nicht auf Trigger-Features der Datenbank aufbauen. Basic-SQL reicht auch. Und Polling stört hier keinen. Eher noch würde bei bei häufigeren Updates unnötig getriggert werden, wenn eine weniger häufige Anzeigenänderung ausreicht. (Meine Annahme: #DatenUpdates > #AnzeigeUpdates => Pollen besser als Triggern)

  • Ich würde ein internes Modell von dem was du anzeigen möchtest aufbauen. (Quasi Model-View-ViewModel pattern). Also einfach ein Mapping von Reihe auf deine Zahl.
  • Jetzt gibt es eine Komponente (Methode) die mit der SQL-Abfrage-Aggregation dieses Dictionary aktualisiert.
  • Jetzt gibts ne zweite Komponente, die die Werte in dem Dict an die Anzeigen nacheinander sendet.
  • Einen einzigen Timer, der erst Methode 1 und danach Methode 2 aufruft.

So bleibt es erstmal einfach.
Die Trennung in zwei Komponenten und das interne Modell macht es einfacher, Änderungen einzubauen.

Wenn du immer mehr anzeigen bekommst, und das TCP-Pakete absenden "skalieren" muss, kannst du diese Methode intern auf parallel-for oder Async-TCP Methoden umstellen.

Wenn die Datenbankabfragen zu aufwändig werden, kannst du diesen anderen Teil auch umstellen, vielleicht eines Tages auf Trigger, oder häufigere Updates, oder oder. Die einzige Schnittstelle ist das Model.

Und so lange du nur einen einzeigen Timer verwendest, musst du auch nicht über synchronisierte Zugriffe auf das interne Modell nachdenken.

beste Grüße
zommi

49.485 Beiträge seit 2005
vor 9 Jahren

Hallo zommi,

im Raum standen 1000 Aktualisierungen pro Sekunde mit einem unbekannten Aufwand für die Ermittlung der Änderungen bzw. des aktuellen Stand. Außerdem hatte ich geschrieben, dass man nur Maßnahmen ergreifen muss, wenn dadurch zu viel Last entsteht. Also gerade nicht premature.

herbivore