Reactive Behavior in Object-oriented Applications: An ... · [Functional reactive animation,...

65
Reactive Behavior in Object-oriented Applications: An Analysis and a Research Roadmap Guido Salvaneschi Mira Mezini Software Technology Group, University of Darmstadt

Transcript of Reactive Behavior in Object-oriented Applications: An ... · [Functional reactive animation,...

Reactive Behavior in Object-oriented Applications: An Analysis and a

Research Roadmap

Guido Salvaneschi

Mira MeziniSoftware Technology Group, University of Darmstadt

Outline

• Design space of OO reactive applications

• Empirical case studies

• Advanced languages for reactive applications

• Research roadmap

IDENTIFYING THE DESIGN SPACEReactive Applications in OO Languages

• External/internal events trigger a reaction

– User input

– Network packet

– Interrupt

– Data from sensors

• Classic example:

– Data change in MVC

Reactive Applications

• Derived graph (D): edges exceeding MIN weight

• Add an edge to the Basic graph (B) !

Strategies for Reactivity: Graphs

BASIC DERIVEDComputational dependency

D = B.filter(edge > MIN)

• On-demand recomputation

• Caching

• Tracking dependencies

• Update incrementalization

• Accumulating changes

Strategies for Reactivity: Graphs

On Demand Recomputation

“Recompute the D each time it is needed”

– Request from the client• Generate a report, refresh a view, …

– Recompute D

– Discard

• Simple: just compute the outputs from inputs.

• Safe/consistent: values are always computed from the current state of the program

• Memory efficient

Caching

“Save the D for further requests”

– Store D

– Request from the client• If the D is valid return it

• otherwise recompute D

– Changes invalidate D

• When the inputs change: invalidate/recompute

– Is the computed value is used frequently?

Tracking dependencies

“Update only the outputs that depend on changed input”

– Store B with the edges sorted

– Recompute D from scratch

– Only a subset of B is evaluated

• Hard: knowledge of input-output computational relations

• Dataflow is not explicit in imperative code

– Code analysis is required to reconstruct it.

Update incrementalization

“Update the cached value incrementally”

– Keep always the same D– Update D only if

weight(newEdge) > MIN

• For complex objects more efficient than recomputation

• Fine-grained analysis of the changes to the inputs. – Change detection is not enough. Which change?

• Need for incremental algorithms – E.g. D is the Minimum Spanning Tree of the B !?

Accumulating changes

“Store the changes” – Cache D

– Store the changes

– Apply changes at least when D is requested

• Requires caching and incrementalization

• More complex than updating after each change– Data structures to store the changes

– Sophisticated algorithms for the update.

• Opportunities for optimization!

CASE STUDIESImplementing Reactivity in OO Applications

Applications

• SWT Text Editor: editor in the SWT library• FreeCol Game: open-source turn-based strategy game • Apache JMeter: performance assessment of servers• AccelerometerPlay: example Android application

Analysis

• Static analysis / dynamic measurements / instrumentation via AspectJ / (a lot of) manual inspection (sigh…)

• What we have found:– Code Complexity

– Hidden Design Intent

– Redundant Computations

– Scattering and Tangling of Update Code

– Error-proneness and Code Repetitions

Issues of Implementing Reactivity

• Complexity

– SWT StyledText• 70 mutable fields

• Handlers/listeners = 40 methods

• Hidden Design Intent

– AccelerometerPlay

• Redundancy

• Scattering and tangling

– Worst case: field updated in 96 places!

Complexity of Reactivity

• SWT StyledText ~10,000 LOC

– 70 mutable fields

– “addListener”+“removeListener”+“handleEvent” = 40 methods

• Efficient data structures

• Values are separated from their update logic

– Local reasoning is impossible: understanding the application requires inspecting a lot of code

Hidden Design Intent

• Accelerometer Play

– https://play.google.com/store/apps/

Redundancy of Computation

• AspectJ probes

– Method executions in the Freecol game

– Freecol game Vs SWT Text editor

Update code

• Scattering and tangling

• Fields is updated in just one place:

– FreeCol game: 38.4%,

– Jmeter: 46.0%

– SWT text editor: 30.7%

– In the worst case, a field was updated in 96 places!

Lesson Learned: Modularization

• Modularization of update code is hard in the OO style

– Dependencies are not explicit and span over several modules

– Updates code scattering and tangling

Lesson Learned: Consistency

• Manual update is error-prone

– Fail to update all functionally dependent values.

– Values are often updated defensively no clear knowledge of whether it is necessary.

Lesson Learned: Maintenance

• No automatic consistency of the update code with the actual dependencies of the computation.

• Update the update functionality to reflect the current state of the dependencies!

Lesson Learned: Design

• Trade-off: efficiency Vs complexity.

– Keep the design simple: accept the cost of on-demand recomputation and potential redundancy.

– Optimization: highly complicates the application • Complex update logic

• Object fields for intermediate caching

ADVANCED LANGUAGESState of the art in reactive applications

The (good? old) Observer Pattern

Decoupling the code that changes a value from the code that updates the values depending on it

• Long story of criticism…

– Inversion of natural dependency order

– Boilerplate code

– Reactions do not compose

– Scattering and tangling of triggering code

– …

Event-based Languages

• Event-based languages are better!– Language-level support for events

– C#, Ptolemy, EScala, …

• Features:– Integration with OO

and imperative style: • Fine-grained updates

• Object identity

– More composable

– Less boilerplate code

abstract class Figure {evt moved[Unit] = afterExec(moveBy)evt resized[Unit]evt changed[Unit] = resized || moved || afterExec(setColor)evt invalidated[Rectangle] = changed.map( _ => getBounds() )

...def moveBy(dx: Int, dy: Int) { position.move(dx, dy) }def resize(s: Size) { size = s }def setColor(col: Color) { color = col }def getBounds(): Rectangle

...}

Event-based Languages

• Dependencies still encoded manually– Handler registration

• Updates must be implemented explicitly – In the handlers

• Dependents notifications is still error prone: – Too rarely / too often

• No support fornon-functional choices– E.g. manual caching

– Accumulation of changes ?

class Connector(val start: Figure, val end: Figure) {start.changed += updateStartend.changed += updateEnd

...def updateStart() { ... }def updateEnd() { ... }

Reactive Languages

• Functional-reactive programming (FRP) -- Haskell

– Time-changing values as dedicated language abstractions. [Functional reactive animation, Elliott and Hudak. ICFP ’97]

• More recently:

– FrTime [Embedding dynamic dataflow in a call-by-value language, Cooper and Krishnamurthi, ESOP’06]

– Flapjax [Flapjax: a programming language for Ajax applications.

Meyerovich et al. OOPSLA’09]

– Scala.React [Imaier te al, Deprecating the Observer Pattern with Scala.React. Technical report, 2012]

Reactive Languages

• Functional-reactive programming (FRP) -- Haskell

– Time-changing values as dedicated language abstractions.

var nowB = timerB(1000);

var startTm = nowB.valueNow();

var clickTmsB = $E("reset", "click").snapshotE(nowB)

.startsWith(startTm);

var elapsedB = nowB − clickTmsB;

insertValueB(elapsedB, "curTime", "innerHTML");

<body onload="loader()">

<input id="reset" type="button" value="Reset"/>

<div id="curTime"> </div>

</body>

[Flapjax: a programming language for Ajax applications. Meyerovich et al. OOPSLA’09]

(Functional) Reactive Languages

• Functional flavor and immutability.

– Refactoring to a functional style ?

– Some computations are hard to express functionally

• Objects: modeling, modularization, Reuse, Runtime variability, …

Reactive Languages

• Several issues in the case studies are solved!– Dependent values automatically consistent

• Simpler applications

• No update errors

– The update code modularized with the entity• Local reasoning

• No scattering and tangling

– Reactive behaviors are composable• In contrast to callbacks, which return void

• Design intentions are explicit

• Declarative style

var elapsedB = nowB − clickTmsB;

(Functional) Reactive Languages

• Do not fit well with mutable objects.

– Reactive languages recompute the dependents every time• E.g. require immutable data structures

– Changes to the state of the object are not even detected

list2 = list1.filter(x>10)

var elapsedB = nowB − clickTmsB;

Reactive Collections

• Efficient incremental updates

– “View maintenance” in the database community

[Deriving production rules for incremental view maintenance. S. Ceri and J. Widom. VLDB’91]

L1

L2 = f (L1)

L3 = g (L2)

Reactive Collections

• Language extensions / libraries

– Intercepting the updates via AspectJ, code generation[Caching and incrementalization in the Java query language, D. Willis et al.

OOPSLA’08]

[Generating incremental implementations of object-set queries, T. Rothameland Y. A. Liu, GPCE’08]

– Off-the-shelf libraries: LiveLinq , Glazed Lists (e.g. JabRef).

Reactive Collections

• Efficient incremental updates, LiveLinq, Glazed Lists

– “View maintenance” in the database community

L1

L2 = f (L1)

L3 = g (L2)

EventList cars = new BasicEventList();EventList sorted = new SortedList(cars);TextFilterList filtered = new TextFilterList(sorted);filtered.getFilterEdit().setText("Hybrid");

cars.add("Insight");cars.add("EV1");cars.add("Prius Hybrid");cars.add("Jetta TDI");cars.add("Escape Hybrid");cars.add("Escalade");

// should print "[Escape Hybrid, Prius Hybrid]"System.out.println(filtered);

Reactive Collections

• Advantages similar to reactive languages

– Automatic updates!

• Efficient update of various operators

– Incremental changes /caching

• Approach restricted to a specific domain / operators

Aspect-oriented Programming

“Intercept object changes, update dependent entities”

– (Crosscutting) update functionalities are separated

public abstract class Figure {...

public void moveBy(int dx, int dy) {position.move(dx, dy);

}public void setColor(Color col) {

color = col;}

} public aspect FigureEvents {pointcut changed(): execution( void Figure+.moveBy( ... ) )

|| execution( void Figure+.setColor( ... ) );}

Aspect-oriented Programming

• Success stories:– (Observer) Pattern with AOP

• [Design pattern impl. in Java and AspectJ, Hannemann and Kiczales, OOPSLA’02]

– Combination with events and OO• [Gasiunas et al, EScala: modular event-driven object interactions in Scala, AOSD ’11]

– Complex relations among objects• [Association aspects, Sakurai et al. AOSD ’04]

• [Relationship aspects , Pearce and Noble. AOSD ’06]

• Many limitations of events hold for AOP, too. – Explicit updates in the aspect

– Dependencies are not automatically tracked

– Composition of reactive behaviors is harder compared to FRP.

Other Approaches

• Constraint-based languages

– Kaleidoscope

• One-way constraints

– Graphical interfaces, Garnet and Amulet

• Self-adjusting computation

– Automatic derivation of incremental programs

• Complex event processing (CEP)

– TelegraphCQ, SASE, EventJava

Summary

• Event-based languagesFit into the OO design, mutable objects / fine-grained changes

Not declarative.

Drawbacks of Observer

• Reactive languagesOvercome the limitations of Observer

Declarative style

No fine grained changes / mutable objects, no integration with OO

• Reactive collectionsEfficient, declarative

Single domain

RESEARCH ROADMAP

Roadmap

Reactive languages

• Integration with Event-based Programming

• Integration with Object-oriented Design

• Efficient Reactive Expressions

• Propagation Model

Roadmap

Reactive languages

• Integration with Event-based Programming

• Integration with Object-oriented Design

• Efficient Reactive Expressions

• Propagation Model

Integration of Reactive Programming and Event-based Programming

• Events and reactive abstractions are complementary

• Interface• *Signal → Event+ Signal.changed

• *Event → Signal+ Event.latest

• *(S, E) → Signal+ snapshot

• Methodology

– When to use behaviors and when events

– Case studies and guidelines

– Patterns ?

EVENTS SIGNALS

Roadmap

Reactive languages

• Integration with Event-based Programming

• Integration with Object-oriented Design

• Efficient Reactive Expressions

• Propagation Model

Objects

• Modeling: reproduce the interaction of real world entities.– For example, the hundreds of simulation elements used by the FreeCol game

• Modularizing functionalities and abstracting over implementation details. – SWT widgets are ready-to-use, but open for modifications via subtyping– E.g., the SWT text editor implementation for text container, can be overridden

• Reuse by class inheritance. – E.g., the StyledText class is part of an inheritance hierarchy of depth 7.

• Runtime variability. via dynamic polymorphism. – Simulation elements in JMeter are treated uniformly and late bound.– In the SWT, a text editor can be used wherever a generic widget is expected.

Integration of Reactive Programming and Object-oriented Design

• Methodological/design issues

– Encapsulation

– Behaviors should be part of the interface ?• Private behaviors?

– Reassign behavior expressions ?

– Inheritance of behaviors ?

– Subtype polymorphism ?

[Crossing state lines: Adapting object-oriented frameworks to functional reactive languages, Ignatoff et al, FLOPS’06]

Roadmap

Reactive languages

• Integration with Event-based Programming

• Integration with Object-oriented Design

• Efficient Reactive Expressions

• Propagation Model

Efficient Reactive Expressions

• Reactive collections

– Optimizations are out-of-the-box for built-in operators

…but not at the fingertips of end developers

• Reactive languages

– Arbitrary reactive computations

…not so efficient

Efficient Reactive Expressions: Challenge!

• Reconciling the openness of reactive languages with the efficiency of reactive collections

Openness

Efficiency

Reactive collections

Reactive Languages ?

Efficient Reactive Expressions (1)

• Predefined operators cover the most common scenarios e.g. collections and relational operations.

• Interoperability with reactive abstractions

s = list1.filter(x>K).size

behaviors

Efficient Reactive Expressions (2)

• Domain knowledge enables incremental updates.– Open refinements of reactive computations !

– Can be easy as overriding an existing method ?

• Separate creation from maintenance

• Default : complete recomputation

• Late binding of the best refinement

• Generality of mechanism Vs domain-specific incrementalization

list2 = list1.filter(x>10)

Roadmap

Reactive languages

• Integration with Event-based Programming

• Integration with Object-oriented Design

• Efficient Reactive Expressions

• Propagation Model

Propagation Model: Intro

• Graph model

– Constraints among dependent values

– Change propagation

f = 1g = 1

c := f + g // c == 2

f = 2 // c == 3

c

f g

Propagation Model: Intro

c := f + g

b := e * 100

d = true

a := { if(d) c else b }

a

b

cd

ef g

Propagation Model: Strategies

• Current languages: single point in the design space

– Caching with invalidation ?

– Proactive recomputation ?

– Caching of intermediate values ?

– Accumulate changes ?

– Adaptive mechanism ?

a

b

cd

ef g

Propagation Model: Collapsing

• Optimizations

– Alternative graphs can be observationally equivalent

– Performance can guide the choice.• Caching Vs moving to the stack

a

b c

d

e f

a

b

c(e(y),f(z))x

y z y z

x

Propagation Model: Collapsing

• Choose carefully!– Code analysis / dynamic techniques?

(time-consuming-op

(infrequently-changing-op frequent-emitter))

d

f

z

t

z

t

d ·f

Propagation Model: VMs

• Dedicated VM support ?

• Graph:

– Events

– Time-changing values

• Previous work: dedicated VM support for AOP[Efficient control flow quantification, Bockisch et al, OOPSLA’06]

Propagation Model

• Espressive power impacts on performance– Speculative execution of signal expressions– Dynamic creation of signals– Exact tracking of dependencies– …

• Current reactive languages focus on expressive power rather than performance– FRP (Haskell), FrTime, Scala.React,

• Esterel and LUSTRE, limit expressive power to achieve better performance– Memory and time-bound execution

a

b

cd

e

f g

Propagation Model

• Current languages: expressive power

– E.g. dynamic signal creation

• Dataflow languages: performance

– Lustre, Esterel: memory and time-bound execution

• Black-or-white choice

• Leave the programmer the choice!

– Whole range available

– Explicit performance implications

Ongoing!

• ERC grant PACE, Prof. Mira Mezini

• Programming Abstractions for Applicationsin Cloud Environments

– http://www.stg.tu-darmstadt.de/index.en.jsp

Interested ? Contact us!

Ongoing: REScala

• REScala: R(eactive)EScala

– Development methodology for reactive applications

– Systematic evaluation by case studies

– Tech report is out! • http://www.stg.tu-darmstadt.de/research/escala/index.en.jsp

Reactive abstractions

Advanced event system+

QUESTIONS ?Thank you !

Take Away

• Reactive applications are an important research area.

• Current solutions go only half the way:

– Known to be flawed (Observer)

– Promising (reactive programming)

– Specific for a single domain (reactive collections)

• Merge of those techniques

• Integration with OO programming