リアクティブプログラミングに
おける事変値永続化の試み
紙名 哲⽣(⼤分⼤学)
2021年2⽉24⽇
第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
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
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
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
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
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
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
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
Stopwatch as a flow b/w TVVs
Button
Activation
Counter
Time
Label
State changes by the
main button
2021/2/24 第2回ステアラボソフトウェア技術セミナー 10
Stopwatch as a flow b/w TVVs
Button
Activation
Counter
Time
Label
Label of main button is
switching
2021/2/24 第2回ステアラボソフトウェア技術セミナー 11
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
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
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
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
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
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
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
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
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(𝑏)
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
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
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
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.
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
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
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
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
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
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
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
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
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?
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.
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
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
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.
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
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
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)
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
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
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
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”);
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

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

  • 1.
  • 2.
    Outline of thistalk 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) uAbstractionsfor 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 twostates: 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 booleanisActive = 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 booleanisActive = 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 booleanisActive = 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 booleanisActive = 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 aflow b/w TVVs Button Activation Counter Time Label Counter is moving only when it is active 2021/2/24 第2回ステアラボソフトウェア技術セミナー 9
  • 10.
    Stopwatch as aflow b/w TVVs Button Activation Counter Time Label State changes by the main button 2021/2/24 第2回ステアラボソフトウェア技術セミナー 10
  • 11.
    Stopwatch as aflow b/w TVVs Button Activation Counter Time Label Label of main button is switching 2021/2/24 第2回ステアラボソフトウェア技術セミナー 11
  • 12.
    Stopwatch as aflow 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 TVVin 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 RPLanguages 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 pushesto 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/methodsto 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 withinpropagation 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 reconfigurationof 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 uInteractiveapplications 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 simpleJava-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 uDeclaredusing 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 amodifier 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 uFoldingoperators 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 uPropagationoccurs 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 uTimeproceeds 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 uUpdateof “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 uMostlythe 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-seriesdata? 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 withtheir 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 uAssumingposX 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 persistentsignals 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 thatpackages 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 eachinstance 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 asan 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:050.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 signalsonly 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 uIDshould 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 persistentsignals 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 uLocationtransparency 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 asystem 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