Title: Data Driven Programming
1Data Driven Programming Change Nets
Dr. Werner Van Belle e-mail werner.van.belle_at_bio6
.itek.norut.no e-mail werner_at_onlinux.be Phone
47 776 29 404
11 November 2005
21. Connections
3Connections
- Multiple 'actors' that can be
- separated in time
- separated in space
- Communicate through connections
- shared data
- self contained (messages)
- Different implementation flavors
- processes, threads, thunks, longjumps,
callbacks,... - copy-on-write, fetch-on-access, serialization
4Connection Based Programming
- Provides
- loose coupling every actor can connect any two
different actors - actors do not need to know to whom they will be
connected - dissociation of control flow and code send and
forget - suitable for distributed systems
- efficient local execution (10x slower than
function calls) - increased flexibility rerouting of connections,
multiple receivers
5Program Layout
- Programming larger applications consists of
- combining methods and functions to bring a
program from one state to another - to be modular, often a mixture of
- action calls ('print out this file')
- state reactions ('queue contains file to print')
- Focus here on state 'reactive' programming
- a natural use of connections
62. Updates
7Updating strategy
- Change the variable or data content
- Send out a change notification
- Listeners receive update and 'react' to the new
state - Advantage
- Efficient for both message based and thread based
connection models. - Disadvantage
- update loops
8Scenario
- Queue
- push(string)
- pop()
- PrintingQueue
- relies on a 'waiting' queue for data storage
- pops, prints, stops, pops, prints, stops, ...
How to functionally connect these two objects ?
9Scenario
- Connect a Queue state change to the PrintingQueue
void Queuepush(string s)
files.push_back(s) updated()
direct connection (call / callback)
Update Loop at waiting-gtpop() !
string Queuepop() string s
files.pop_front() updated() return
s
void PrintingQueuestate_changed() if
(printing) return string s waiting-gtpop()
printingtrue
10(No Transcript)
11(No Transcript)
12(No Transcript)
13Update Loops
- Direct loops avoided using distinct names
- poppop_without_update
- pop_updatepush_update
- pop_from_printer_queuepop_from_other_actor
- Leads to
- unclear naming convention usage dependency
- indirect conflicts with extra actors (log
connected to queue) - multi hop loops tend to be difficult to avoid
14Update Loops
- Other solutions include
- loop breaking using version numbers
- loop breaking using locking
- loop breaking points using comparison checks
- All of these can work but they tend to be
scattered throughout the code ! - Control flow of the overall program is difficult
to understand
153. Formal State Transition
16Petri-Nets
- Tokens a piece of data, a message
17Petri-Nets
- Places contain zero, one or more tokens
18Petri-Nets
- Transitions can move tokens between places
- can fire when all inputs provide a suitable token
(pre-condition / guarding) - when fired, removes all input tokens and creates
new output tokens (post-condition) - fire atomically (no concurrent transitions)
19The Printing Queue Petri-Net
20Petri-Nets
21Petri-Nets
22Petri-Nets
- Advantages
- Good program documentation
- Possibility to simulate message flow, without
working program - Formal proof of boundedness, reachability
(homestate), deadlock-freedom - Efficient implementation through
locality-principle
Can we use Petri-nets as a change notification
mechanism ?
23Tracking Change with Petri-Nets
24Petri-Nets
- Disadvantages
- Formal guard requirements are too broad to
implement efficiently (search for a matching
binding problem). - Programming with Petri-nets difficult because
tokens are consumed. All state is volatile.
Petri-nets are good for constraint checking They
fail to provide natural change tracking
capabilities
25Change Nets
- Modification to Petri-nets
- There is always exactly one token per place.
- Transition are extended with 'might-be-enabled'
flag. - 'might-be-enabled' is updated whenever any of the
input places changes state - Once 'might-be-enabled', the constraint
associated with the transition can be checked - Then the transition can be fired
1. Change messages are separated in time -gt no
direct loop updates 2. Change messages are only
send if change occurs -gt no indirect loops 3.
Multiple changes result in one change message per
listener 4. Change messages do no contain the
data -gt lightweight
26No update Loops
varltintgt a(0) varltintgt b(0) varltintgt
c(0) a.update_to(b) b.update_to(c)
c.update_to(a) a10
27Queue
class Queue public Place listltstringgt
files void push(string s)
files.push_back(s) updated()
string pop() string s
files.front() files.pop_front()
updated() return s
28PrintingQueue
class PrintingQueue Queue waiting
varltboolgt printing PrintingQueue(Queue q)
void state_changed()
PrintingQueuePrintingQueue(Queue q)
waiting(q) new MemberTransitionltPrintingQueuegt(
this, PrintingQueuestate) -gtreact_on(waiting)
-gtreact_on(printing) printing false
29PrintingQueue
void PrintingQueuestate_changed() if
(printing) return string s waiting-gtpop()
printingtrue
Queue q new Queue() PrintingQueue
pq1(q) PrintingQueue pq2(q)
q-gtpush("File1") q-gtpush("File2")
30Multi-Threaded Change Nets
- Transition waits for a changed state
- Clear state
- Sorted waiting acquisition of input locks
output locks - Checks constraints
- Execute transition
- Releases locks
31Intermediate Conclusion
- Petri-nets are a natural way to think about state
changes in programs - Change nets well defined based on Petri-nets (can
be automatically generated in function of the
constraint net) - Change net transitions provide a clear,
transparent way to glue programs together - Change nets can be efficiently implemented in
process, thread thunk based execution models.
324. Implementation
33Places
class Place // all the listeners to state
changes on this place vectorltTransitiongt
output_transitions public void
update_to(Transitiont) output_transitions.push_b
ack(t) // will update all the output
transitions 'changed' state void updated()
void Placeupdated() for(int i 0 i lt
output_transitions.size() i)
output_transitionsi.input_place_changedtrue
34Transitions
class Transition bool input_place_changed
// might_be_enabled // will create a
transition and add it to the global net
Transition() // will mark this transition as
'possible' executable void set_input_place_chan
ged() input_place_changedtrue // will
inform this transition to react on changes at
place void react_on(Placep)
p-gtupdate_to(this) // will check the
might_be_enabled state and run if necessary
void execute() virtual void run() 0
void Transitionexecute() if
(!input_place_changed) return
input_place_changed false run()
35Convenience Classes - Variables
template ltclass Tgt class var public Place T
value public varltTgt() Place()
varltTgt(T init) Place(), value(init) void
update_to(varltTgt other) operator const
T(void) return value operator const
T(void) const return value varltTgt
operator (const varltTgt f) varltTgt operator
(const T f)
36Convenience Classes - Variables
template ltclass Tgt varltTgt varltTgtoperator
(const varltTgt f) if (valuef.value) return
this valuef updated() return this
37Convenience Classes Member Transitions
template ltclass Hgt class MemberTransition public
Transition public typedef void
(Hmember)() member F H o
MemberTransition(H ob, member i) o(ob)
Fi virtual void run() ((o).(F))()
38Conclusion
- Petri-nets are a natural way to think about state
changes in programs - Change nets well defined based on Petri-nets (can
be automatically generated in function of the
constraint net) - Change net transitions provide a clear,
transparent way to glue programs together - Change nets can be efficiently implemented in
process, thread thunk based execution models.
395. Extra Trolltech Connections
40Connections - Trolltech
- Multi-threaded
- Signals emit function calls
- Slots accepts function calls
On an i586-500, you can emit around 2,000,000
signals per second connected to one receiver, or
around 1,200,000 per second connected to two
receivers. The simplicity and flexibility of the
signals and slots mechanism is well worth the
overhead, which your users won't even notice.
41Connections - Trolltech
42Connections - Trolltech
include ltQObjectgt class Counter public
QObject Q_OBJECT int m_value
public Counter() m_value 0
int value() const return m_value public
slots void setValue(int value)
signals void valueChanged(int newValue)
43Connections - Trolltech
void CountersetValue(int value) if
(value ! m_value) m_value value
emit valueChanged(value)
44Connections - Trolltech
class LcdNumber public QFrame Q_OBJECT
public LcdNumber(QWidget parent 0)
public slots void display(int num)
void display(double num) void display(const
QString str) void setHexMode() void
setDecMode() void setOctMode() void
setBinMode() void setSmallDecimalPoint(bool
point)
45Connections - Trolltech
Counter a new Counter()LcdNumber l new
LcdNumber()connect(a,SIGNAL(valueChanged(int)),
l,SLOT(display(int)))