© Zühlke 2014
Mit reaktiver Programmierung über
den Acker
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2....
© Zühlke 2014
Who_Am_I?
• Informationstechnik im
Maschinenwesen
• Road behind:
– Chemical Engineering
– Walzwerke
– Hotelb...
© Zühlke 2014
Reaktive Programmierung: Warum?
• Eventaggregatoren gezielt
einsetzen
• Schöner Testen mir Rx
• Push vs. Pul...
© Zühlke 2014
Das Projekt
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 4
© Zühlke 2014
Systemsicht
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
ECU
- Fährt
- Regelt
- Navigiert
-...
© Zühlke 2014
Projekt-Charakteristika
Regelung 
Ablaufsteuerung
•Workflows mit
„Stateless“
Viele unfertige
Umsysteme
•Not...
© Zühlke 2014
Klassische Kommunikation
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
• Interfaces müssen u...
© Zühlke 2014Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
Weitere Abhängigkeiten beim Testen
Component
A
...
© Zühlke 2014
Entkopplung durch Events
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
„Tell don‘t ask“
Comp...
© Zühlke 2014
Statusübergänge durch Events
Umsysteme/
Simulation
erzeugen
Events
States lösen
wiederum
Events aus
•Ersatzg...
© Zühlke 2014
Weitere Eventquellen
2. Dezember 2014
Verknüpfung mit Reactive Extensions
Mit reaktiver Programmierung über ...
© Zühlke 2014
Reactive Extensions für jedermann
.NET
JavaScript
(RxJS)
Java (RxJava)
+ Scala,
Groovy,
Clojure
Objective-C
...
© Zühlke 20142. Dezember 2014
IEnumerable  IObservable
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Foli...
© Zühlke 20142. Dezember 2014
Eigenschaften eines IObservers
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth...
© Zühlke 2014
EventAggregatoren mit Rx
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
public class EventAgg...
© Zühlke 2014
Grobe Systemarchitektur
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
ECU
CAN-Bus
Business-
...
© Zühlke 2014
Klassisches Testen 1/2
Warten auf das „hoffentlich bald“-Event
Mit reaktiver Programmierung über den Acker |...
© Zühlke 2014
Klassisches Testen 2/2
Warten auf das „hoffentlich bald“-Event
Mit reaktiver Programmierung über den Acker |...
© Zühlke 2014
Eventgetriebenes Testen
Gegeben:
• Man kann mit EventAggregator Events erzeugen und sich auf Events
subscrib...
© Zühlke 2014
Testen von UI über Events 1/2
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
ViewModel
Workfl...
© Zühlke 2014
Testen von UI über Events 2/2
© Zühlke 2014
ISchedulerProvider und TestScheduler 1/2
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
m_eve...
© Zühlke 2014
ISchedulerProvider und TestScheduler 2/2
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
m_eve...
© Zühlke 2014
Nutzen von Rx TestSchedulern
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
• Simulation von ...
© Zühlke 2014
Die vierte Dimension: Zeit
• Viewmodel: Events werden auf dispatcher
thread observed
• Viewmodels nutzen ISc...
© Zühlke 2014
Eventgetrieben im Vergleich zu SOA
• Request/response vs. Observable-
Pattern
• EventAggregator als ServiceB...
© Zühlke 2014
Ausflug ins Reactive Manifesto
Reactive
Mani-
festo
Respon-
sive
Resilient
Elastic
Message
Driven
Mit reakti...
© Zühlke 2014
Vor- und Nachteile reaktiver Programme
• Voraussetzung in mobile OS‘s
• Push-Notifications bei Apps
• Mobile...
© Zühlke 2014
Events als festen Bestandteil im Projekt
Logging
Tracing
Events
•Debug-Info
•Fehlersuche
•Performance-Counte...
© Zühlke 2014
Take-Aways
Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
Dauerbrenner
Lightweight
Architectu...
© Zühlke 2014Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth
Haben Sie Fragen?
Stefan.Roth@zuehlke.com
@half...
Nächste SlideShare
Wird geladen in …5
×

Mit reaktiver Programmierung über den Acker

1.090 Aufrufe

Veröffentlicht am

Softwareprojekte beginnen selten auf der grünen Wiese. Meist bestehen zahlreiche Abhängigkeiten zu Zulieferungen, die sich der eigenen Kontrolle entziehen. Der Fortschritt der eigenen Entwicklung gerät in Gefahr, wenn sich diese Zulieferungen verspäten, anfangs nicht den vereinbarten Qualitätsansprüchen genügen oder ständigem Wandel unterzogen sind. Wie kommt man unter solchen Rahmenbedingungen dennoch voran? Ein möglicher Ansatzpunkt sind reaktive Anwendungsarchitekturen, die sich aktuell in aller Munde befinden.

Was bringt dieser Technologieansatz im echten Projekt? Wo sind die Chancen, wo die Risiken? Wie kann man sich im Projektalltag schrittweise an Reactive Extensions herantasten? Wie helfen sie beim Testen von zeitabhängigem, nebenläufigem Code? Anhand eines konkreten Projektbeispiels eines Navigationssystems für Agrarfahrzeuge auf dem Feld möchte ich Antworten auf diese Fragen geben.

Veröffentlicht in: Software
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
1.090
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
22
Aktionen
Geteilt
0
Downloads
8
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Mit reaktiver Programmierung über den Acker

  1. 1. © Zühlke 2014 Mit reaktiver Programmierung über den Acker Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 1
  2. 2. © Zühlke 2014 Who_Am_I? • Informationstechnik im Maschinenwesen • Road behind: – Chemical Engineering – Walzwerke – Hotelbuchungssysteme – Brauereien und Abfüllanlagen • Seit 2010 Software Engineer bei der Zühlke GmbH in Eschborn • Schwerpunkte: – M2M – Innovation Stefan Roth Marburg Berlin Grenoble Erlangen Nürnberg München Regensburg, Darmstadt Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth stefan.roth@zuehlke.com Dr.stefan.roth@googlemail.com @halfwit_twit 2. Dezember 2014 Folie 2
  3. 3. © Zühlke 2014 Reaktive Programmierung: Warum? • Eventaggregatoren gezielt einsetzen • Schöner Testen mir Rx • Push vs. Pull Oder besser: Warum eigentlich nicht? Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 3
  4. 4. © Zühlke 2014 Das Projekt Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 4
  5. 5. © Zühlke 2014 Systemsicht Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth ECU - Fährt - Regelt - Navigiert - Kalibriert GPS - Positions- daten Navigations- rechner -Verfahrwege - Spuren Feld- Daten - Feldkonturen - gesp. Tracks - Fahrzeugdaten - Peripherie Panel - UI - Karte - Fahrzeugdaten - Steuerung ? ? ? 2. Dezember 2014 Folie 5
  6. 6. © Zühlke 2014 Projekt-Charakteristika Regelung  Ablaufsteuerung •Workflows mit „Stateless“ Viele unfertige Umsysteme •Notwendigkeit der Simulation Asynchronität Unklare/Unfertige Requirements States und Ereignisse •Kleinster gemeinsamer Nenner Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 6
  7. 7. © Zühlke 2014 Klassische Kommunikation Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth • Interfaces müssen untereinander bekannt sein • Player müssen sich gegenseitig „kennen“ oder Polling 2. Dezember 2014 Folie 7
  8. 8. © Zühlke 2014Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Weitere Abhängigkeiten beim Testen Component A Component B DoSomething (X, Y) Component B’ DoSomethingElse (X, Q, Z) ? Unit tests ? 2. Dezember 2014 Folie 8
  9. 9. © Zühlke 2014 Entkopplung durch Events Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth „Tell don‘t ask“ Component A Component B User triggered action X Subscribed to events of type X Component B’ Just produced: result Y Subscribed to result events of type Y Just produced: result Y Just produced: result Z Just produced: result Q 2. Dezember 2014 Folie 9
  10. 10. © Zühlke 2014 Statusübergänge durch Events Umsysteme/ Simulation erzeugen Events States lösen wiederum Events aus •ErsatzgrößeZeitvariant •Nebenläufige Threads und Timer Spezielles Setup oder Alltag? Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 10
  11. 11. © Zühlke 2014 Weitere Eventquellen 2. Dezember 2014 Verknüpfung mit Reactive Extensions Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Folie 11 PositionECU
  12. 12. © Zühlke 2014 Reactive Extensions für jedermann .NET JavaScript (RxJS) Java (RxJava) + Scala, Groovy, Clojure Objective-C (Reactive Cocoa) C++ (RxCpp) Python Ruby PHP Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Rx = Observables + LINQ + Schedulers. 2. Dezember 2014 Folie 12
  13. 13. © Zühlke 20142. Dezember 2014 IEnumerable  IObservable Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Folie 13 1 Rückgabewert n Rückgabewerte T IEnumerable<T> Pull: 1 Rückgabewert n Rückgabewerte Task<T> IObservable<T> Push: public interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); }
  14. 14. © Zühlke 20142. Dezember 2014 Eigenschaften eines IObservers Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Folie 14 public interface IObserver<in T> { void OnNext(T value); void OnError(Exception error); void OnCompleted(); }
  15. 15. © Zühlke 2014 EventAggregatoren mit Rx Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth public class EventAggregator : IEventAggregator { private readonly ISubject<object> messageSubject = new Subject<object>(); public IObservable<object> EventStream { get { return this.messageSubject; } } public void Send<T>(T message) { this.messageSubject.OnNext(message); } public void Send<T>(T message, IScheduler scheduler) { if (scheduler == null) { this.Send(message); } else { scheduler.Schedule(() => Send(message)); } } public IObservable<T> GetEventStream<T>() { return this.messageSubject.OfType<T>(); } } 2. Dezember 2014 Folie 15
  16. 16. © Zühlke 2014 Grobe Systemarchitektur Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth ECU CAN-Bus Business- Logik/Workflows UI Services ECU Message translator EventAggregator 2. Dezember 2014 Folie 16
  17. 17. © Zühlke 2014 Klassisches Testen 1/2 Warten auf das „hoffentlich bald“-Event Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth bool status = false; while (!status) { status = m_target.Status == expectedStatus; } Target pollen target.SelectedEcuOrientation = ExpectedEcuOrientation; this.ContainingViewModel.NextStepCommand.Execute(null); var completion = new ManualResetEvent(false); machineCalibrationService.GetECUOrientation( ecu => { readEcuOrientation = ecu; completion.Set(); }); completion.WaitOne(); 2. Dezember 2014 Folie 17 Mit Synchronisierungsartefakten
  18. 18. © Zühlke 2014 Klassisches Testen 2/2 Warten auf das „hoffentlich bald“-Event Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth • Synchronisierungs-Artefakten • Asynchrone Tests  Boilerplate code • Ausweg: Async/Await. Sonst: • Warten heißt Thread blockieren • Timings unterschiedlich in Dev- und Build-Umgebung • Tests ungeeignet für continuous integration 2. Dezember 2014 Folie 18
  19. 19. © Zühlke 2014 Eventgetriebenes Testen Gegeben: • Man kann mit EventAggregator Events erzeugen und sich auf Events subscriben. • EventAggregator als Singleton überall injectbar Gesucht: • Wie warte ich auf Events? – Muss ich das wirklich tun? • UI-Tests Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 19 Voraussetzungen und Fragen
  20. 20. © Zühlke 2014 Testen von UI über Events 1/2 Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth ViewModel Workflows Unit-Test View 2. Dezember 2014 Folie 20
  21. 21. © Zühlke 2014 Testen von UI über Events 2/2
  22. 22. © Zühlke 2014 ISchedulerProvider und TestScheduler 1/2 Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth m_eventAggregator.GetEventStream<FineWheelAngleSensorCalibrationResult>() .ObserveOnDispatcher() .Subscribe( (result) => { Status = result.Status; if (result.Status == CalibrationFineWheelAngleSensorStatus.Completed) { Parent.NextStepAvailable = true; } }); /// <summary> /// Gets the <see cref="IScheduler"/> instance representing the current app's thread /// </summary> public IScheduler CurrentThread { get { return Scheduler.CurrentThread; } } /// <summary> /// Gets the <see cref="IScheduler"/> instance representing dispatching thread. /// </summary> public IScheduler Dispatcher { get { return DispatcherScheduler.Instance; } } class SchedulerProvider «interface» ISchedulerProvider «Property» - CurrentThread :IScheduler - Dispatcher :IScheduler - Immediate :IScheduler - NewThread :IScheduler - ThreadPool :IScheduler TestSchedulers {leaf} - m_currentThread :TestScheduler = new TestScheduler() {readOnly} - m_dispatcher :TestScheduler = new TestScheduler() {readOnly} - m_immediate :TestScheduler = new TestScheduler() {readOnly} - m_newThread :TestScheduler = new TestScheduler() {readOnly} - m_threadPool :TestScheduler = new TestScheduler() {readOnly} «property» + CurrentThread() :TestScheduler + Dispatcher() :TestScheduler + Immediate() :TestScheduler + NewThread() :TestScheduler + ThreadPool() :TestScheduler SchedulerProvider «property» + CurrentThread() :IScheduler + Dispatcher() :IScheduler + Immediate() :IScheduler + NewThread() :IScheduler + ThreadPool() :IScheduler Default-SchedulerProvider: 2. Dezember 2014 Folie 22
  23. 23. © Zühlke 2014 ISchedulerProvider und TestScheduler 2/2 Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth m_eventAggregator.GetEventStream<FineWheelAngleSensorCalibrationResult>() .Subscribe( (result) => { Status = result.Status; if (result.Status == CalibrationFineWheelAngleSensorStatus.Completed) { Parent.NextStepAvailable = true; } }); /// <summary> /// Gets the <see cref="IScheduler"/> instance representing the current app's thread /// </summary> public IScheduler CurrentThread { get { return Scheduler.CurrentThread; } } /// <summary> /// Gets the <see cref="IScheduler"/> instance representing dispatching thread. /// </summary> public IScheduler Dispatcher { get { return DispatcherScheduler.Instance; } } class SchedulerProvider «interface» ISchedulerProvider «Property» - CurrentThread :IScheduler - Dispatcher :IScheduler - Immediate :IScheduler - NewThread :IScheduler - ThreadPool :IScheduler TestSchedulers {leaf} - m_currentThread :TestScheduler = new TestScheduler() {readOnly} - m_dispatcher :TestScheduler = new TestScheduler() {readOnly} - m_immediate :TestScheduler = new TestScheduler() {readOnly} - m_newThread :TestScheduler = new TestScheduler() {readOnly} - m_threadPool :TestScheduler = new TestScheduler() {readOnly} «property» + CurrentThread() :TestScheduler + Dispatcher() :TestScheduler + Immediate() :TestScheduler + NewThread() :TestScheduler + ThreadPool() :TestScheduler SchedulerProvider «property» + CurrentThread() :IScheduler + Dispatcher() :IScheduler + Immediate() :IScheduler + NewThread() :IScheduler + ThreadPool() :IScheduler Default-SchedulerProvider: .ObserveOn(schedulerProvider.Dispatcher) 2. Dezember 2014 Folie 23
  24. 24. © Zühlke 2014 Nutzen von Rx TestSchedulern Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth • Simulation von Ereignissen durch Scheduling zu vordefinierten Zeiten • Scheduler vor und nach Event “spulen” • Verschiedene Threads  verschiedene Scheduler • Zeit = weiterer Freiheitsgrad • Zeitvarianter Test der dennoch in wenigen ms ausgeführt wird // advance schdeuler to one tick before PCU event: this.TestScheduler.Dispatcher.AdvanceBy(1999); Assert.AreEqual(YYY.PointBIsSet, this.m_target.Status); Assert.IsFalse(this.m_target.AutopilotActivatedCommand.CanExecute(nu ll)); // advance two ticks further to simulate the PCU firing the // automatic steering possible event: this.TestScheduler.Dispatcher.AdvanceBy(2); Assert.AreEqual(YYY.AutomaticSteeringPossible,this.m_target.Status); Assert.IsTrue(this.m_target.AutopilotActivatedCommand.CanExecute(nul l)); // schedule that after 2000 ticks the PCU will signal the ”automatic // steering possible” signal: this.TestScheduler.Dispatcher.Schedule( TimeSpan.FromTicks(2000), () => this.m_eventAggregator.Send(XXX.AutomaticSteeringPossible)); 2. Dezember 2014 Folie 24
  25. 25. © Zühlke 2014 Die vierte Dimension: Zeit • Viewmodel: Events werden auf dispatcher thread observed • Viewmodels nutzen ISchedulerProvider • Rx TestScheduler machen Zeit „programmierbar“ – Virtuelle Zeit – Zeitmaschine – Unit tests Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 25
  26. 26. © Zühlke 2014 Eventgetrieben im Vergleich zu SOA • Request/response vs. Observable- Pattern • EventAggregator als ServiceBus? • Nur noch event aggregator? • Ist das noch punk „reaktiv“? Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 26
  27. 27. © Zühlke 2014 Ausflug ins Reactive Manifesto Reactive Mani- festo Respon- sive Resilient Elastic Message Driven Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth http://www.reactivemanifesto.org/ • Flexible • Loosely coupled • Scalable 2. Dezember 2014 Folie 27
  28. 28. © Zühlke 2014 Vor- und Nachteile reaktiver Programme • Voraussetzung in mobile OS‘s • Push-Notifications bei Apps • Mobile Apps und Taskwechsel • Daher Push vs. Pull fast schon Dogma • Reactive Extensions: Ansatz Eventverarbeitung und Asynchronität über Programmiersprachen hinaus gleich zu behandeln • Kein Silver Bullet – Verständnis von Asynchronität weiter unabdingbar – Verklemmung und Verhungern weiter möglich • Preis: – Verlust des Contracts und der Signatur – Debugging-Hell Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth 2. Dezember 2014 Folie 28
  29. 29. © Zühlke 2014 Events als festen Bestandteil im Projekt Logging Tracing Events •Debug-Info •Fehlersuche •Performance-Counter •Info über Zustandsänderungen •Testbarkeit erhöhen •In Ergänzung zu Services 2. Dezember 2014Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Folie 29
  30. 30. © Zühlke 2014 Take-Aways Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Dauerbrenner Lightweight Architecture Lose gekoppelte Systeme Dependency Injection YAGNI, KISS Services mit definierter Verantwort- lichkeit Evolutionäre Architektur Vermeiden von unnötigen Schichten Zeitabhängig- keit durch Events lösen 2. Dezember 2014 Folie 30
  31. 31. © Zühlke 2014Mit reaktiver Programmierung über den Acker | Dr. Stefan Roth Haben Sie Fragen? Stefan.Roth@zuehlke.com @halfwit_twit 2. Dezember 2014 Folie 31

×