Advertisement
Advertisement

More Related Content

More from STAIR Lab, Chiba Institute of Technology(20)

Advertisement

リアクティブプログラミングにおける時変値永続化の試み (第2回ステアラボソフトウェア技術セミナー)

  1. リアクティブプログラミングに おける事変値永続化の試み 紙名 哲⽣(⼤分⼤学) 2021年2⽉24⽇ 第2回ステアラボソフトウェア技術セミナー
  2. Outline of this talk uIntroduction to Reactive Programming (RP) uSignalJ: a simple Java-based RP language uPersistent signals: challenges & current solutions 2021/2/24 第2回ステアラボソフトウェア技術セミナー 2
  3. Reactive Programming (RP) uAbstractions for time-varying values (TVVs) uContinuously changing values ue.g., current time uStreams of timed values ue.g., events triggered by users' actions uDeclarative dependencies uPropagation b/w TVVs uConsidered useful for "reactive systems" uGUI, sensors & actuators, … 2021/2/24 第2回ステアラボソフトウェア技術セミナー 3
  4. Stopwatch Example uHaving two states: active and inactive uCounter is moving only when it is active uState is changed by pressing the main button uThe label of main button is switching uactive → "Stop", inactive → "Start" uThe reset button set the counter zero, and make the stopwatch inactive (not moving) 2021/2/24 第2回ステアラボソフトウェア技術セミナー 4
  5. Stopwatch by Java boolean isActive = false; Thread th = null; public void actionPerformed(ActionEvent e) { if (e.getSource() == start) { if (isActive) { isActive = false; start.setLabel("Start"); th = null; } else { isActive = true; start.setLabel("Stop"); th = new Thread(this); th.start(); } } else { isActive = false; start.setLabel("Start"); th = null; textField.setText("0.0"); } } public void run() { … /* counter behavior */ } Counter is moving only when it is active 2021/2/24 第2回ステアラボソフトウェア技術セミナー 5
  6. Stopwatch by Java boolean isActive = false; Thread th = null; public void actionPerformed(ActionEvent e) { if (e.getSource() == start) { if (isActive) { isActive = false; start.setLabel("Start"); th = null; } else { isActive = true; start.setLabel("Stop"); th = new Thread(this); th.start(); } } else { isActive = false; start.setLabel("Start"); th = null; textField.setText("0.0"); } } public void run() { … /* counter behavior */ } State changes by the main button 2021/2/24 第2回ステアラボソフトウェア技術セミナー 6
  7. Stopwatch by Java boolean isActive = false; Thread th = null; public void actionPerformed(ActionEvent e) { if (e.getSource() == start) { if (isActive) { isActive = false; start.setLabel("Start"); th = null; } else { isActive = true; start.setLabel("Stop"); th = new Thread(this); th.start(); } } else { isActive = false; start.setLabel("Start"); th = null; textField.setText("0.0"); } } public void run() { … /* counter behavior */ } Label of main button is switching 2021/2/24 第2回ステアラボソフトウェア技術セミナー 7
  8. Stopwatch by Java boolean isActive = false; Thread th = null; public void actionPerformed(ActionEvent e) { if (e.getSource() == start) { if (isActive) { isActive = false; start.setLabel("Start"); th = null; } else { isActive = true; start.setLabel("Stop"); th = new Thread(this); th.start(); } } else { isActive = false; start.setLabel("Start"); th = null; textField.setText("0.0"); } } public void run() { … /* counter behavior */ } Reset button set the counter zero and make the watch inactive 2021/2/24 第2回ステアラボソフトウェア技術セミナー 8
  9. Stopwatch as a flow b/w TVVs Button Activation Counter Time Label Counter is moving only when it is active 2021/2/24 第2回ステアラボソフトウェア技術セミナー 9
  10. Stopwatch as a flow b/w TVVs Button Activation Counter Time Label State changes by the main button 2021/2/24 第2回ステアラボソフトウェア技術セミナー 10
  11. Stopwatch as a flow b/w TVVs Button Activation Counter Time Label Label of main button is switching 2021/2/24 第2回ステアラボソフトウェア技術セミナー 11
  12. Stopwatch as a flow b/w TVVs Button Activation Counter Time Label Reset button set the counter zero and make the watch inactive 2021/2/24 第2回ステアラボソフトウェア技術セミナー 12
  13. Abstractions of TVV in RP uFRP uBehavior: continuous time-varying values uEvent: discrete values uReactive extensions (e.g., RxJava) uFlowable: publisher of values uObservable: consumer of values uSubject/Processor: both of publisher & consumer uSignalJ uSignal 2021/2/24 第2回ステアラボソフトウェア技術セミナー 13
  14. Stopwatch by RxJava BehaviorSubject<Button> buttonSeq = BehaviorSubject.create(); BehaviorSubject<Boolean> activation = BehaviorSubject.create(); BehaviorSubject<Integer> counter = BehaviorSubject.create(); Observable<String> label = activation.map(x -> x ? "Stop" : "Start"); Flowable<Long> time = Flowable.interval(100, TimeUnit.MILLISECONDS); … time.subscribe(x -> { if (activation.getValue()) { counter.onNext(counter.getValue() + 1); } }); buttonSeq.subscribe(b -> { if (b == start) { activation.onNext(!activation.getValue()); } else { counter.onNext(0); activation.onNext(false); } }); Counter is moving only when it is active 2021/2/24 第2回ステアラボソフトウェア技術セミナー 14
  15. Stopwatch by RxJava BehaviorSubject<Button> buttonSeq = BehaviorSubject.create(); BehaviorSubject<Boolean> activation = BehaviorSubject.create(); BehaviorSubject<Integer> counter = BehaviorSubject.create(); Observable<String> label = activation.map(x -> x ? "Stop" : "Start"); Flowable<Long> time = Flowable.interval(100, TimeUnit.MILLISECONDS); … time.subscribe(x -> { if (activation.getValue()) { counter.onNext(counter.getValue() + 1); } }); buttonSeq.subscribe(b -> { if (b == start) { activation.onNext(!activation.getValue()); } else { counter.onNext(0); activation.onNext(false); } }); State changes by the main button 2021/2/24 第2回ステアラボソフトウェア技術セミナー 15
  16. Stopwatch by RxJava BehaviorSubject<Button> buttonSeq = BehaviorSubject.create(); BehaviorSubject<Boolean> activation = BehaviorSubject.create(); BehaviorSubject<Integer> counter = BehaviorSubject.create(); Observable<String> label = activation.map(x -> x ? "Stop" : "Start"); Flowable<Long> time = Flowable.interval(100, TimeUnit.MILLISECONDS); … time.subscribe(x -> { if (activation.getValue()) { counter.onNext(counter.getValue() + 1); } }); buttonSeq.subscribe(b -> { if (b == start) { activation.onNext(!activation.getValue()); } else { timer.onNext(0); activation.onNext(false); } }); Label of main button is switching 2021/2/24 第2回ステアラボソフトウェア技術セミナー 16
  17. Stopwatch by RxJava BehaviorSubject<Button> buttonSeq = BehaviorSubject.create(); BehaviorSubject<Boolean> activation = BehaviorSubject.create(); BehaviorSubject<Integer> timer = BehaviorSubject.create(); Observable<String> label = activation.map(x -> x ? "Stop" : "Start"); Flowable<Long> time = Flowable.interval(100, TimeUnit.MILLISECONDS); … time.subscribe(x -> { if (activation.getValue()) { timer.onNext(timer.getValue() + 1); } }); buttonSeq.subscribe(b -> { if (b == start) { activation.onNext(!activation.getValue()); } else { counter.onNext(0); activation.onNext(false); } }); Reset button set the counter zero and make the watch inactive 2021/2/24 第2回ステアラボソフトウェア技術セミナー 17
  18. Taxonomy of RP Languages uExisting RP languages uFran, Yampa, Flapjax, Rx, REScala, SignalJ, … uDesign spaces uEvaluation strategy uLifting uGlitch avoidance uSupport for switching uSupport for distribution E. Bainomugisha et al., A Survey on Reactive Programming, ACM Computing Surveys, 45(4), 2013. 2021/2/24 第2回ステアラボソフトウェア技術セミナー 18
  19. Evaluation Strategies uPush-based uProducer pushes to the consumer uSuitable for event-driven reactions uGlitch avoidance is necessary uPull-based uConsumer triggers computation on demand uNo glitches uUnable to represent `instantaneous' reaction Producer Consumer flow of data push Producer Consumer flow of data pull 2021/2/24 第2回ステアラボソフトウェア技術セミナー 19
  20. Lifting uConverting existing operators/methods to operate on TVV uNecessary when embedded on the host language ureturning value of 𝑓 at current time uExplicit lifting: uStatically typed languages uImplicit lifting: uDynamic languages 2021/2/24 第2回ステアラボソフトウェア技術セミナー 20 lift ∶ 𝑓(𝑇) → 𝑓lifted(𝑇𝑉𝑉 < 𝑇 >) 𝑓(𝑏) → 𝑓lifted(𝑏) lift(𝑓)(𝑏) → 𝑓lifted(𝑏)
  21. Glitches uTemporal inconsistency within propagation uGlitch avoidance uTopological sorting is necessary in push- strategy uDifficult in distributed setting 2021/2/24 第2回ステアラボソフトウェア技術セミナー 21 var1 var2 var3 *2 + var2 = var1*2 var3 = var1+var2 var1 var2 var3 1 2 ? 3 2 4 4 6
  22. Switching propagations uDynamic reconfiguration of propagations uFRP languages typically provide switching combinators 2021/2/24 第2回ステアラボソフトウェア技術セミナー 22 var4 = if var1 then var2 * var3 else var2 + var3 var2 var3 + var2 var3 * var4 var1 T F
  23. Support for Distribution uInteractive applications are becoming increasingly distributed uWeb applications, mobile applications, … uMore difficult to ensure consistency within propagations ulatency, network failure, … uKnown approaches uUsing a central coordinator uCan be a bottleneck, failures affect the entire system uDistributed decentralized propagation algorithm uIntensive research on distributed systems 2021/2/24 第2回ステアラボソフトウェア技術セミナー 23
  24. SignalJ: a simple Java-based RP language uSimplified programming interface uSupporting events and FRP-like propagation using one abstraction uNo lifting: signals are 'compatible' with normal values uSupporting rich expressive power of RP uPush-pull, glitch-freedom, switching support, and side-effects 2021/2/24 第2回ステアラボソフトウェア技術セミナー 24 T. Kamina and T. Aotani, Harmonizing Signals and Events with a Lightweight, Extension to Java, The Arts, Science, and Engineering of Programming, 2(3), 2018.
  25. Signals in SignalJ uDeclared using the modifier signal uComposite signal uAutomatically reevaluated by propagation uReassignment is disallowed uSource signal uCan be updated imperatively signal int a = 5; signal int b = a + 3; a++; System.out.println(b); source signal composite signal 9 2021/2/24 第2回ステアラボソフトウェア技術セミナー 25
  26. signal as a modifier uNo lifting uA signal can appear on any places where non- signal is expected signal int a = 6; signal int count = Integer.bitCount(a); a++; System.out.println(count); 3 • Dependency is statically determined • The type system considered their types are int 2021/2/24 第2回ステアラボソフトウェア技術セミナー 26
  27. API-based operators uEvent handling uFolding operators signal int a = 5; a.subscribe(e -> System.out.println(e)); a++; Handler is called in response to this update signal int a = 5; a++; System.out.println(a.sum()); 11 2021/2/24 第2回ステアラボソフトウェア技術セミナー 27
  28. Evaluation strategies: signals uPropagation occurs immediately udiff and sensorValue change at the same time uEvaluation is mostly pull-based uFolding operators are eagerly evaluated signal int sensorValue = …; signal int sum = sensorValue.sum(); signal int diff = P*sensorValue + I*sum; PI control 2021/2/24 第2回ステアラボソフトウェア技術セミナー 28
  29. Evaluation strategies: events uTime proceeds after event firing ulast is updated after sensorValue is updated uOutputs for motors are performed after diff is updated int last = …; sensorValue.subscribe(x -> last = x); signal int diff = P*sensorValue + I*sum + D*(sensorValue - last); diff.subscribe(x -> setMotors(x)); PID control 2021/2/24 第2回ステアラボソフトウェア技術セミナー 29
  30. Changing signal networks uUpdate of “a signal of objects” is considered switching signal int tabIndex = 0; List tabs = new List().add(new View()); signal View currentView = tabs.getViewByIndex(tabIndex); 2021/2/24 第2回ステアラボソフトウェア技術セミナー 30 tabIndex currentView view1: View content view2: View content
  31. Stopwatch in SignalJ uMostly the same structure with RxJava (w/ simpler syntax) signal Button buttonSeq = reset; signal boolean activation = false; signal int counter = 0; signal String label = activation ? "Stop" : "Start"; Timer time = new SimpleCounter(counter, 100); … activation.subscribe(x -> { if (x) time.start(); else time.stop() }); buttonSeq.subscribe(b -> { if (b == start) { activation != activation; } else { counter = 0; activation = false; } }); 2021/2/24 第2回ステアラボソフトウェア技術セミナー 31
  32. Signal as time-series data? uTVVs are everywhere uWeather, IoT sensors, SNS, … uUpdated over time uPersistent data queried by time uOften used in reactive systems uDo signals provide suitable abstraction? uSignals are transient, not supporting queries 2021/2/24 第2回ステアラボソフトウェア技術セミナー 32
  33. Vehicle tracking example 2021/2/24 第2回ステアラボソフトウェア技術セミナー 33 x y v … selected time xt yt vt position of the vehicle estimated velocity vehicle tracking record (history of updated values) (displayed values) Can we represent this as 'propagations' as well?
  34. Persistent Signals uSignals with their execution histories persistent signal double posX, posY; SERIAL: id TIMESTAMP: time DOUBLE: value 1 2020-08-01'T'12:34:00 131.605591 2 2020-08-01'T'12:34:05 131.605956 3 2020-08-01'T'12:34:11 131.606385 … … … Internally, mapping to time-series database is maintained 2021/2/24 第2回ステアラボソフトウェア技術セミナー 34 T. Kamina and T. Aotani, An Approach for Persistent Time-Varying Values, In Onward! 2019.
  35. Propagation by views uAssuming posX and posY are updated at the same time, views ensure the consistency persistent signal double posX, posY; signal double dx = posX.lastDiff(1); signal double dy = posY.lastDiff(1); signai double v = dx.distance(dy); CREATE VIEW dy AS SELECT x.id AS id, x.value-y.value AS value FROM posX as x, (SELECT id,value FROM posY OFFSET 1) as y WHERE x.id = y.id-1 view-creating API is prepared 'in advance' 2021/2/24 第2回ステアラボソフトウェア技術セミナー 35
  36. Problems of persistent signals uNot providing abstractions for representing complex data structures uUsing signals for each x- and y-coordinates instead of using a signal representing "a vehicle" uSimultaneity of updates of coordinates are not imposed by the language, but maintained by the programmer uPropagating only by predefined API uCannot be created dynamically uNot supporting switching of propagation 2021/2/24 第2回ステアラボソフトウェア技術セミナー 36
  37. Signal Classes uClass that packages related persistent signals signal class Vehicle { persistent signal double x, y; signal double dx = x.lastDiff(1); signal double dy = y.lastDiff(1); signai double v = dx.distance(dy); Vehicle(String id) { … } … } Vehicle v = new Vehicle("Oita_a_1234"); v.set(33.240240, 131.611679); Permanently identifying an object • Unit of synchronization • Unit of lifecycle management 2021/2/24 第2回ステアラボソフトウェア技術セミナー 37 T. Kamina et al., Managing Persistent Signals using Signal Classes, In REBLS 2020.
  38. Lifecycle Model uManaging each instance with unique ID uInterface for lifecycle management DB table is created with the fresh ID Instance exists on the disk even after the application stops Instance resumes with the previous state public interface SignalClassInstance { set(Object... args); reset(); destroy(); } 2021/2/24 第2回ステアラボソフトウェア技術セミナー 38
  39. Time-oriented queries uImplemented as an API-based operator uPropagated to every enclosed persistent signals 2021/2/24 第2回ステアラボソフトウェア技術セミナー 39 Vehicle v = new Vehicle("Oita_a_1234"); Timer t = new Timer(v, 10000, v::setPosition); Vehicle mirror = new Vehicle("Oita_a_1234"); … mirror.snapshot(slider.getValue()); Viewer application (not expected to set the vehicle's position) Tracking application
  40. TIMESTAMP: time value 2020-08-01'T'12:34:05 0.000043 2020-08-01'T'12:34:11 0.000102 … … Propagation uTimestamp is assigned for each set 2021/2/24 第2回ステアラボソフトウェア技術セミナー 40 Vehicle v = new Vehicle("Oita_a_1234"); Timer t = new Timer(v, 10000, v::setPosition); double[] current = getGeographicCoordinates(); set(current[0],current[1]); TIMESTAMP: time x y travelled 2020-08-01'T'12:34:00 131.605591 33.240240 0.1 2020-08-01'T'12:34:05 131.605956 33.239148 0.3 … … 1. Every propagation is calculated (push-based) 2. Inserted to the table with a timestamp dx *views are still supported by API methods (pull-based)
  41. Switching propagation uPersistent signals only support primitive types uOne exception: signal class types uSupport of switching 2021/2/24 第2回ステアラボソフトウェア技術セミナー 41 signal class Monitor { persistent signal Vehicle v; public Monitor(String id) { … } } Monitor m = new Monitor("aMonitor"); m.set(aCar); // DB records its identifier
  42. Issues remain uID resolution uID should be unique, but currently no mechanisms to ensure uniqueness uRefactoring and migration uEvolution of signal classes uSignal classes using existing time-series data 2021/2/24 第2回ステアラボソフトウェア技術セミナー 42
  43. Distributed RP and persistent signals uRequired: time-series data are glitch-free uThen, every observation is consistent! uAssumption: every entry has its timestamp uGlobal clock, Lamport uProperties characterizing glitches uTiming uConsistency: total order, causal, … uCan distributed DB provide a platform for considering these properties? 2021/2/24 第2回ステアラボソフトウェア技術セミナー 43
  44. Toward multi-tier signals uLocation transparency supported by IDs 2021/2/24 第2回ステアラボソフトウェア技術セミナー 44 Distributed time-series DB Vehicle v = new Vehicle(“ID9999”); Traffic r210 = new Traffic(“R210”); r210.addVehicle(“ID9999”);
  45. Summary uRP represents a system as a flow b/w TVVs uSignalJ provides a simple abstraction for TVVs uEvery TVV is a signal uSimple programming interface uNo lifting, push-pull, API-based operators uPersistent signals provide an abstraction for TVVs as time-series data uSignal classes manage their lifecycles and identities uLocation transparency 2021/2/24 第2回ステアラボソフトウェア技術セミナー 45
Advertisement