Loetkolben Geschrieben January 2, 2014 at 00:06 Geschrieben January 2, 2014 at 00:06 Hallo zusammen, wenn 2 Sender (Programme die aufs Remote Switch Bricklet zugreifen) mehrere Steckdosen ueber das gleiche Remote Switch Bricklet schalten wollen und dies zur gleichen Zeit tun, dann wird der "zweite" Befehl evtl verworfen, da der erste Befehl noch ausgefuehrt wird. So habe ich zumindest die Doku verstanden. Nun gibt es ja den Befehl "get_switching_state": (Gibt den aktuellen Zustand des Schaltens zurück. Wenn der aktuell Zustand busy (beschäftigt) ist, sendet das Bricklet gerade einen Code um eine Steckdose zu schalten. Weitere Aufrufe von switch_socket werden ignoriert bis der Zustand auf ready (fertig) wechselt.) Das hilft aber auch nicht, wenn beide "Sender" dies abfragen und ein "frei" bekommen und dann senden. Darum mein Vorschlag den Befehl "get_switching_state" um 2 Paramter zu erweitern, die eine Reservierung ermoeglichen: - Set_Booking (0 bis 255 Sekunden) - Booking_ID (0 bis 255) (Von User frei wahlbar) Wenn 0 dann wird der Befehl wie bisher verarbeitet. Eine >0 dann das Bricklet fuer x Sekunden exklusiv gebucht. Als Rueckgabewert kommt dann eine 0 fuer nicht moeglich oder eine 1 fuer akzeptiert zurueck. Damit kann man dann im 2. Schritt den Befehl zum Bricklet senden und man weiss ganz genau, dass der auch verarbeitet wird. Warum noch eine Booking ID? Wie soll man sonst die Buchung zuordnen? Wenn man das ueber die Anfragenden IP Adresse macht, koennte es Konflikte geben wenn beide "Sender" von der gleichen IP Adresse aus senden. So kann der User eine ID festlegen und gibt sie beim senden nochmals mit. Alternativ koennte man auch die "switch_socket_x" Befehle um Antworten erweitern, so dass man weiss ob der Befehl angenommen wurde. Dann koennte derjenige "Sender" dessen Paket verworfen wurde ein zweites mal senden und hoffen, dass dann keine Konflikte vorliegen. -> Irgendwie finde ich diese Alternative schicker als den eigentlichen Vorschlag, aber ich lasse das mal alles so stehen. Der Loetkolben Zitieren
AuronX Geschrieben January 2, 2014 at 09:00 Geschrieben January 2, 2014 at 09:00 Nur von mir als Senf: Ich finde die Alternative auch schicker, weil der Booking-Mechanismus eigentlich zu "groß" für das Problem ist (viel Aufwand in Implementierung und für den Nutzer auch im Verständnis). Die Alternative ist einfach zu verstehen und kann vom Nutzer völlig ignoriert werden wenn er nur einen "Sender" hat. Außerdem ist sie mindestens auf Ebene der Bindings kompatibel zum alten Methodenruf (Auf IP-Ebene gibt es eine neue Antwort) Zitieren
Temp Geschrieben January 2, 2014 at 10:29 Geschrieben January 2, 2014 at 10:29 Ich hatte ein ähnliches Problem. "GetSwitchingState" in C# hat nicht zuverlässig gearbeitet. Meine Lösung war das ich vor dem Senden den zugriff mit einer Variable sperre und den CallBack abwarte, der dann die Variable freigibt und den nächsten Sender das go gibt. Vielleicht hilft dir das weiter. Zitieren
nItroFreeZer Geschrieben January 2, 2014 at 17:35 Geschrieben January 2, 2014 at 17:35 Oder man bastelt sich eine Queue und arbeitet mit der Callback-Methode. Sobald alles abgearbeitet wurde, prüft man regelmäßig ob neue Switch-Aufträge anstehen und startet dann ggf. wieder durch. @Temp: Damit hast du theoretisch genau die gleiche Konflikt-Möglichkeit. Ob du nun eine selbst definierte Variable oder via get_switching_state() prüfst, macht nun erstmal keinen Unterschied. Allenfalls die Antwortzeit könnte sich unterscheiden. Grüße nItro Zitieren
Temp Geschrieben January 2, 2014 at 18:15 Geschrieben January 2, 2014 at 18:15 @nItroFreeZer Das stimmt rein Theoretisch wäre die gleiche Konflikt Möglichkeit da, aber ich habe durch das rum Testen die Erfahrung gemacht, das wenn der CallBack aufgerufen wird dann auch wirklich der nächste Senden kann. Beim "get_switching_state()" habe ich die Erfahrung gemacht das es nicht immer funktioniert hat, wenn der Zustand „Ready“ zurückkommt mit den C# Bindings. Zitieren
AuronX Geschrieben January 3, 2014 at 10:04 Geschrieben January 3, 2014 at 10:04 Also grundsätzlich kann man im eigenen Code (und in einem Programm) durch Locking usw schon dafür sorgen, dass diese Methoden funktionieren... object switchLock = new object(); void firstAccessor() { lock (switchLock) { if (bricklet.GetSwitchingState() == SWITCHING_STATE_READY) { //do switch } } } void otherAccessor() { lock (switchLock) { if (bricklet.GetSwitchingState() == SWITCHING_STATE_READY) { //do switch on something different } } } Das Problem: Wenn jeder per locking darauf zugreifen würde, dann wäre es ausgeschlossen, dass jemals ein busy zurück kommt. Deswegen ist der Fall, dass man eine Anwendung für alles hat quasi auch ohne TF gelöst. Aber was ist beispielsweise wenn die Clients von Loetkolben auf unterschiedlichen Maschinen oder zumindest ohne gemeinsamen Speicher laufen? Dann wäre es gut, wenn man allein mit TF-Mitteln das Locking realisiert bekommt... Dazu die beiden Vorschläge. Zitieren
borg Geschrieben January 3, 2014 at 10:25 Geschrieben January 3, 2014 at 10:25 Mh, da müssen wir mal gucken. Methoden um etwas erweitern würde die API brechen, das machen wir eigentlich nicht. Deswegen können wir die beiden Vorschläge nicht so ohne weiteres implementieren. Zitieren
kreaktiv Geschrieben January 3, 2014 at 12:44 Geschrieben January 3, 2014 at 12:44 Ich würde begrüssen wenn; die "switch_socket_x" Befehle um Antworten erweitern, so dass man weiss ob der Befehl angenommen wurde. So wie es in anderen Sprachen wie zB. php auch ist. Würde bedeuten dass alle bisherigen Programme weiter laufen, aber bei Bedarf die Antwort, in einer Schleife, ausgewertet werden könnte. Zitieren
Loetkolben Geschrieben January 3, 2014 at 12:50 Autor Geschrieben January 3, 2014 at 12:50 Aber was ist beispielsweise wenn die Clients von Loetkolben auf unterschiedlichen Maschinen oder zumindest ohne gemeinsamen Speicher laufen? Dann wäre es gut, wenn man allein mit TF-Mitteln das Locking realisiert bekommt... Dazu die beiden Vorschläge. Ups. Hatte ich vergessen das zu sagen? Ja, die Programme laufen auf verschienen Servern, sonst koennte man das mit Flags regeln. Zum einen auf einem Cronjobserver und zum anderen auf mehreren "Webfernbedienungen" via Handy. Aber wieso wuerde die API gebrochen, wenn der Stack eine Antwort liefern wuerde ob der Befehle angenommen oder verworfen wird? Der Loetkolben Zitieren
AuronX Geschrieben January 3, 2014 at 17:48 Geschrieben January 3, 2014 at 17:48 Was wären denn die Konsequenzen aus einer zusätzlichen Antwort? Also ja: Die API würde streng genommen gebrochen, aber was passiert dann? Für jemanden der mit neuer Firmware auch neue Bindings nutzt Nichts, denn aus void wird int (o.ä.) und das ist echt ungefährlich. Nahezu jeder Code sollte vorher und nachher kompilieren (Ausnahme: Func<TResult, ...>). Einziges Problem: Neues Timing + Es kann Timeouts geben Für jemanden mit neuer Firmware und alten Bindings Das ist mir nicht ganz klar... ich glaube aber mich zu erinnern, dass unerwartete Antworten von den Bindings verworfen werden... sollte also gar kein Problem sein. Für jemanden mit neuer Firmware und ohne Bindings (TCP) Okay... der hat je nachdem wie er es implementiert hat wirklich ein Problem... aber ich weiß nicht wie wichtig dieser Use Case ist... Frage: Ist das vertretbar? (Habt ihr so viele Nutzer die das tatsächlich schmerzen würde) (jetzt kommt der allgemeine Teil) Die Alternative zu solchen inkompatiblen Änderungen ist ja immer nur eine schlechte API. Entweder schlecht weil die existierenden Probleme nicht behoben werden oder schlecht weil es zu viele Methoden gibt die nur aus Kompatibilitätsgründen existieren... Vorschlag: Vielleicht solltet ihr über soetwas wie deprecation nachdenken... Also halt jetzt eine neue Methode einführen die den Rückgabewert hat (und einen ordentlichen Namen) und die alte Methode deprecaten, damit ihr sie in einem halben Jahr löschen könnt... ich fürchte aber, dass das aufgrund eures knappen Speichers auf den Bricklets nicht überall klappen wird... Zitieren
Loetkolben Geschrieben January 3, 2014 at 19:51 Autor Geschrieben January 3, 2014 at 19:51 Für jemanden mit neuer Firmware und ohne Bindings (TCP) Okay... der hat je nachdem wie er es implementiert hat wirklich ein Problem... aber ich weiß nicht wie wichtig dieser Use Case ist... Hallo AuronX. Der hat kein Problem, der hat eine Chance! Ich wuerde mich freuen. Fummelkram, aber das sollte ich hinbekommen. Muss ja nicht sofort sein und mal hoeren was Tinkerforge so sagt. Das Problem wird ja dadurch verschaerft, dass man den Status (On/Off) der Funksteckdosen nicht im Nachhinein abfragen kann. Der Loetkolben Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.