-
Notifications
You must be signed in to change notification settings - Fork 8
/
service.coordinator.html
6811 lines (6677 loc) · 818 KB
/
service.coordinator.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>130 Coordinator Service Specification - OSGi Compendium 8</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1" />
<link rel="home" href="index.html" title="OSGi Compendium" />
<link rel="up" href="index.html" title="OSGi Compendium" />
<link rel="prev" href="service.war.html" title="128 Web Applications Specification" />
<link rel="next" href="service.tr069todmt.html" title="131 TR069 Connector Service Specification" />
<meta name="Section-title" content="130 Coordinator Service Specification" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="images/favicon.png" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="css/custom.css" />
<link rel="stylesheet" type="text/css" href="css/github.css" />
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Ubuntu:regular,bold&subset=Latin" /><script type="text/javascript" src="js/highlight.pack.js"></script><script type="text/javascript" src="js/main.js"></script></head>
<body>
<div id="fullbody">
<div id="header">
<div class="menu-top-container"></div>
<div id="shadow-block"><a class="logo" href="index.html"><img src="images/OSGi.svg" alt="OSGi Working Group Documentation" /><h1>OSGi Compendium Release 8</h1></a></div>
</div>
<div id="mobile-menu-icon">⋮</div>
<div id="column-two">
<div id="content">
<div id="scrollable">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<td width="20%" align="left"><a accesskey="p" href="service.war.html">Prev</a>
</td>
<th width="60%" align="center"> </th>
<td width="20%" align="right"> <a accesskey="n" href="service.tr069todmt.html">Next</a></td>
</tr>
</table>
<hr />
</div>
<div class="chapter">
<div xmlns="" class="titlepage">
<div>
<div>
<h1 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="service.coordinator"></a><span xmlns="" class="number">130</span> Coordinator Service Specification
</h1>
</div>
<div>
<p xmlns="http://www.w3.org/1999/xhtml" class="releaseinfo"><a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator" title="130.5 org.osgi.service.coordinator">Version 1.0</a></p>
</div>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="d0e69139"></a><span xmlns="" class="number">130.1</span> Introduction
</h2>
</div>
</div>
</div>
<p>The OSGi programming model is based on the collaboration of standard
and custom components. In such a model there is no central authority that
has global knowledge of the complete application. Though this lack of
authority can significantly increase reusability (and robustness) there
are times when the activities of the collaborators must be coordinated.
For example, a service that is repeatedly called in a task could optimize
performance by caching intermediate results until it
<span class="emphasis"><em>knew</em></span> the task was ended.
</p>
<p>To know when a task involving multiple collaborators has ended is
the primary purpose of the Coordinator service specification. The
Coordinator service provides a rendezvous for an initiator to create a
Coordination where collaborators can decide to participate. When the
Coordination has ended, all participants are informed.
</p>
<p>This Coordinator service provides an explicit Coordination model,
the Coordination is explicitly passed as a parameter, and an implicit
model where the Coordination is associated with the current thread.
Implicit Coordinations can be nested.
</p>
<p>Coordinators share the coordination aspects of the resource model of
transactions. However, the model is much lighter-weight because it does
not support any of the ACID properties.
</p>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69153"></a><span xmlns="" class="number">130.1.1</span> Essentials
</h3>
</div>
</div>
</div>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><span class="emphasis"><em>Coordination</em></span> - Provide a solution to
allow multiple collaborators to coordinate the outcome of a task
initiated by an initiator.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Initiator</em></span> - An initiator must be able to
initiate a coordination and control the final outcome.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Participants</em></span> - Participants in the task
must be informed when the coordination has ended or failed as well
as being able to terminate the Coordination.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Time-out</em></span> - A Coordination should fail
after a given time-out.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Blocking</em></span> - Provide support for blocking
and serializing access to Participants.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Nesting</em></span> - It must be possible to nest
Coordinations.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Per Thread Model</em></span> - Provide a per-thread
current Coordination model.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Variables</em></span> - Provide a variable space per
Coordination
</p>
</li>
</ul>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69197"></a><span xmlns="" class="number">130.1.2</span> Entities
</h3>
</div>
</div>
</div>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><span class="emphasis"><em>Coordinator</em></span> - A service that can create
and enumerate Coordinations.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Coordination</em></span> - Represents the ongoing
Coordination.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Initiator</em></span> - The party that initiates a
Coordination.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Participant</em></span> - A party that wants to be
informed of the outcome of a Coordination.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>Collaborator</em></span> - Either a participant or
initiator.
</p>
</li>
</ul>
</div>
<div class="figure"><a xmlns="" class="anchor" id="d0e69226"></a><p class="title"><strong>Figure <span xmlns="" class="number">130</span>.1 Class and Service overview</strong></p>
<div class="figure-contents">
<div class="mediaobject" align="center"><img src="images/130-coordinator-classes.png" align="middle" width="630" height="189" alt="Class and Service overview" /></div>
</div>
</div><br class="figure-break" /></div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="d0e69232"></a><span xmlns="" class="number">130.2</span> Usage
</h2>
</div>
</div>
</div>
<p>This section is an introduction in the usage of the Coordinator
service. It is not the formal specification, the normative part starts at
<a xmlns="" class="xref" href="service.coordinator.html#i3151714" title="130.3 Coordinator Service">Coordinator Service</a>. This section leaves out some of the details
for clarity.
</p>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69239"></a><span xmlns="" class="number">130.2.1</span> Synopsis
</h3>
</div>
</div>
</div>
<p>The Coordinator service provides a mechanism for multiple parties
to <span class="emphasis"><em>collaborate</em></span> on a common task without a priori
knowledge of who will collaborate in that task. A collaborator can
participate by adding a <span class="emphasis"><em>Participant</em></span> to the
Coordination. The Coordination will notify the Participants when the
coordination is <span class="emphasis"><em>ended</em></span> or when it is
<span class="emphasis"><em>failed</em></span>.
</p>
<p>Each Coordination has an <span class="emphasis"><em>initiator</em></span> that
creates the <code class="code">Coordination</code> object through the Coordinator
service. The initiator can then push this object on a thread-local stack
to make it an implicit Coordination or it can pass this object around as
a parameter for <span class="emphasis"><em>explicit</em></span> Coordinations.
Collaborators can then use the <span class="emphasis"><em>current</em></span> Coordination
on the stack or get it from a parameter. Whenever a bundle wants to
participate in the Coordination it adds itself to the Coordination as a
participant. If necessary, a collaborator can initiate a new
Coordination, which could be a nested Coordination for implicit
Coordinations.
</p>
<p>A Coordination must be <span class="emphasis"><em>terminated</em></span>.
Termination is either a normal end when the initiator calls the
<code class="code">end</code> method or it is failed when the <code class="code">fail</code>
method is called. A Coordination can be failed by any of the
collaborators. A Coordination can also fail independently due to a
<span class="emphasis"><em>time-out</em></span> or when the initiator releases its
Coordinator service. All participants in the Coordination are informed
in reverse participation order about the outcome in a callback for ended
or failed Coordinations.
</p>
<p>A typical action diagram with a successful outcome is depicted in
<a xmlns="" class="xref" href="service.coordinator.html#service.coordinator-coordination-action" title="Figure 130.2 Action Diagram Implicit Coordination">Figure <span class="number">130</span>.2</a>.
</p>
<div class="figure"><a xmlns="" class="anchor" id="service.coordinator-coordination-action"></a><p class="title"><strong>Figure <span xmlns="" class="number">130</span>.2 Action Diagram Implicit Coordination</strong></p>
<div class="figure-contents">
<div class="mediaobject" align="center"><img src="images/130-coordination-action.png" align="middle" width="562" height="153" alt="Action Diagram Implicit Coordination" /></div>
</div>
</div><br class="figure-break" /></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69294"></a><span xmlns="" class="number">130.2.2</span> Explicit Coordination
</h3>
</div>
</div>
</div>
<p>The general pattern for an initiator is to create a Coordination
through the Coordinator service, perform the work in a try block, catch
any exceptions and fail the Coordination in the catch block, and then
ensure ending the Coordination in the finally block. The finally block
can cause an exception. This is demonstrated in the following
example:
</p><pre xmlns="" class="programlisting"><code>Coordination c = coordinator.create("com.example.work",0);
try {
doWork(c);
} catch( Exception e ) {
c.fail(e);
} finally {
c.end();
}</code></pre><p>This deceptively small template is quite robust:</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>If the <code class="code">doWork</code> method throws an Exception then the
template fails with a Coordination Exception because it is failed in
the try block.
</p>
</li>
<li class="listitem">
<p>Any exceptions thrown in the try block are automatically
causing the Coordination to fail.
</p>
</li>
<li class="listitem">
<p>The Coordination is always terminated and removed from the
stack due to the finally block.
</p>
</li>
<li class="listitem">
<p>All failure paths, Coordinations that are failed by any of the
collaborators, time-outs, or other problems are handled by the
<code class="code">end</code> method in the finally block. It will throw a <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.FAILED" title="130.5.3.4 public static final int FAILED = 2">FAILED</a> or <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.PARTIALLY_ENDED" title="130.5.3.6 public static final int PARTIALLY_ENDED = 3">PARTIALLY_ENDED</a> Coordination Exception for any of the
failures.
</p>
</li>
</ul>
</div>
<p>The different failure paths and their handling is pictured in
<a xmlns="" class="xref" href="service.coordinator.html#i3187111" title="Figure 130.3 Flow through the Coordination template">Figure <span class="number">130</span>.3</a>.
</p>
<div class="figure"><a xmlns="" class="anchor" id="i3187111"></a><p class="title"><strong>Figure <span xmlns="" class="number">130</span>.3 Flow through the Coordination template</strong></p>
<div class="figure-contents">
<div class="mediaobject" align="center"><img src="images/130-coordination-flow.png" align="middle" width="560" height="325" alt="Flow through the Coordination template" /></div>
</div>
</div><br class="figure-break" /><p>The example shows an explicit Coordination because the
<code class="code">create</code> method is used, implicit Coordinations are used in
<a xmlns="" class="xref" href="service.coordinator.html#i3175342" title="130.2.4 Implicit Coordinations">Implicit Coordinations</a>. The parameters of the <code class="code">create</code>
method are the name of the Coordination and its time-out. The name is
used for informational purposes as well as security. For security
reasons, the name must follow the same syntax as the Bundle Symbolic
Name. In a secure environment the name can be used to limit
Coordinations to a limited set of bundles. For example, a set of bundles
signed by a specific signer can use names like <code class="code">com.acme.*</code>
that are denied to all other bundles.
</p>
<p>The zero time-out specifies that the Coordination will not have a
time-out. Otherwise it must be a positive long, indicating the number of
milliseconds the Coordination may take. However, implementations should
have a configurable time-out to ensure that the system remains
alive.
</p>
<p>In the <code class="code">doWork</code> method the real work is done in
conjunction with the collaborators. Explicit Coordinations can be passed
to other threads if needed. Collaborators can decide to add participants
whenever they require a notification when the Coordination has been
terminated. For example, the following code could be called from the
<code class="code">doWork</code> method:
</p><pre xmlns="" class="programlisting"><code>void foo(Coordination c) {
doPrepare();
c.addParticipant(this);
}</code></pre><p>This method does the preparation work but does not finalize it so
that next time it can use some intermediate results. For example, the
<code class="code">prepare</code> method could cache a connection to a database that
should be reused during the Coordination. The collaborator can assume
that it will be called back on either the <code class="code">failed</code> or
<code class="code">ended</code> method. These methods could look like:
</p><pre xmlns="" class="programlisting"><code>public void ended(Coordination c) { doFinish(); }
public void failed(Coordination c) { doFailed(); }</code></pre><p>The Coordinator provides the guarantee that this code will always
call the <code class="code">doFinish</code> method when the Coordination succeeds and
<code class="code">doFailed</code> method when it failed.
</p>
<p>The Participant must be aware that the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Participant.ended-Coordination-" title="130.5.6.1 public void ended(Coordination coordination) throws Exception">ended(Coordination)</a> and <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Participant.failed-Coordination-" title="130.5.6.2 public void failed(Coordination coordination) throws Exception">failed(Coordination)</a> methods can be called on any thread.
</p>
<p>If the <code class="code">doWork</code> method throws an exception it will end
up in the catch block of the initiator. The catch block will then fail
the Coordination by calling the <code class="code">fail</code> method with the given
exception. If the Coordination was already terminated because something
else already had failed it then the method call is ignored, only the
first fail is used, later fails are ignored.
</p>
<p>In all cases, the finally block is executed last. The finally
block ends the Coordination. If this coordination was failed then it
will throw a Coordination Exception detailing the reason of the failure.
Otherwise it will terminate it and notify all the participants.
</p>
<p>The Coordination Exception is a Runtime Exception making it
unnecessary to declare it.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69400"></a><span xmlns="" class="number">130.2.3</span> Multi Threading
</h3>
</div>
</div>
</div>
<p>Explicit Coordinations allow the Coordination objects to be passed
to many different collaborators who can perform the work on different
threads. Each collaborator can fail the Coordination at any moment in
time or the time-out can occur on yet another thread. Participants must
therefore be aware that the callbacks <code class="code">ended</code> and
<code class="code">failed</code> can happen on any thread. The following example
shows a typical case where a task is parallelized. If any thread fails
the Coordination, all other threads could be notified before they're
finished.
</p><pre xmlns="" class="programlisting"><code>Executor executor = ...
final CountDownLatch latch = new CountdownLatch(10);
final Coordination c = coordinator.create("parallel", 0);
for ( int i=0; i<10; i++) {
executor.execute(
new Runnable() {
public void run() { baz(c); latch.countDown(); }
});
}
latch.await();
c.end();</code></pre><p>The <code class="code">Coordination</code> object is thread safe so it can be
freely passed around.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="i3175342"></a><span xmlns="" class="number">130.2.4</span> Implicit Coordinations
</h3>
</div>
</div>
</div>
<p>An explicit Coordination requires that the Coordination is passed
as a parameter to the <code class="code">doWork</code> method. The Coordinator also
supports <span class="emphasis"><em>implicit</em></span> Coordinations. With implicit
Coordinations the Coordinator maintains a thread local stack of
Coordinations where the top of this stack is the
<span class="emphasis"><em>current</em></span> Coordination for that thread. The usage of
the implicit Coordination is almost identical to the explicit
Coordinations except that all the work occurs on a single thread. The
control flow is almost identical to explicit Coordinations:
</p><pre xmlns="" class="programlisting"><code>Coordination c = coordinator.begin("com.example.work",0);
try {
doWork();
} catch( Exception e ) {
c.fail(e);
} finally {
c.end();
}</code></pre><p>See also <a xmlns="" class="xref" href="service.coordinator.html#i3187111" title="Figure 130.3 Flow through the Coordination template">Figure <span class="number">130</span>.3</a>. However, in this case the
finally block with the call to the end method is even more important.
With an implicit Coordination the Coordination is put on a thread local
stack in the <code class="code">begin</code> method and must therefore be popped when
the Coordination is finished. The finally block ensures therefore the
proper cleanup of this thread local stack.
</p>
<p>The difference between implicit and explicit Coordinations is that
the implicit Coordination is not passed as a parameter, instead,
collaborators use the current Coordination. With implicit Coordinations
all method invocations in a thread can always access the current
Coordination, even if they have many intermediates on the stack. The
implicit model allows a collaborator many levels down the stack to
detect a current Coordination and register itself without the need to
modify all intermediate methods to contain a Coordination parameter. The
explicit model has the advantage of explicitness but requires all APIs
to be modified to hold the parameter. This model does not support
passing the parameter through layers that are not aware of the
Coordination. For example, OSGi services in general do not have a
Coordination parameter in their methods making the use of explicit
Coordinations impossible.
</p>
<p>Collaborators can act differently in the presence of a current
Coordination. For example, a collaborator can optimize its work flow
depending on the presence of a current Coordination.
</p><pre xmlns="" class="programlisting"><code>Coordinator coordinator = ...
void foo() {
doPrepare();
if ( !coordinator.addParticipant(this))
doFinish();
}</code></pre><p>The Coordinator service has an <code class="code">addParticipant</code> method
that makes working with the current Coordination simple. If there is a
current Coordination then the Coordinator service will add the
participant and return <code class="code">true</code>, otherwise it returns
<code class="code">false</code>. It is therefore easy to react differently in the
presence of a current Coordination. In the previous example, the
<code class="code">doFinish</code> method will be called immediately if there was no
current Coordination, otherwise it is delayed until the Coordination
fails or succeeds. The participant callbacks look the same as in the
previous section:
</p><pre xmlns="" class="programlisting"><code>public void ended(Coordination c) { doFinish(); }
public void failed(Coordination c) { doFailed(); }</code></pre><p>Though the code looks very similar for the implicit and explicit
Coordinations there are some additional rules for implicit
Coordinations.
</p>
<p>The <code class="code">end</code> method must be called on the same thread as
the <code class="code">begin</code> method, trying to end it on another thread
results in a <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.WRONG_THREAD" title="130.5.3.8 public static final int WRONG_THREAD = 7">WRONG_THREAD</a> Coordination Exception being thrown.
</p>
<p>Even though the <code class="code">end</code> method must be called on the
initiating thread, the callbacks to the Participants can be done on any
thread as the specification allows the Coordinator to use multiple
threads for all callbacks.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69480"></a><span xmlns="" class="number">130.2.5</span> Partial Ending
</h3>
</div>
</div>
</div>
<p>The Coordination is a best effort mechanism to coordinate, not a
transaction model with integrity guarantees. This means that users of
the Coordinator service must understand that there are cases where a
Coordination ends in limbo. This happens when one of the Participants
throws an Exception in the <code class="code">ended</code> callback. This is similar
to a transactional resource manager failing to commit in a 2-phase
commit after it has voted yes in the prepare phase; a problem that is
the cause of much of the complexity of a transaction manager. The
Coordinator is limited to use cases that do not require full ACID
properties and can therefore be much simpler. However, users of the
Coordinator service must be aware of this limitation.
</p>
<p>If a Participant throws an exception in the ended method, the end
method that terminated the Coordination must throw a <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.PARTIALLY_ENDED" title="130.5.3.6 public static final int PARTIALLY_ENDED = 3">PARTIALLY_ENDED</a> Coordination Exception. It is then up to the
initiator to correct the situations. In most cases, this means allowing
the exception to be re-thrown and handle the failure at the top level.
Handling in those cases usually implies logging and continuing.
</p>
<p>The following code shows how the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.PARTIALLY_ENDED" title="130.5.3.6 public static final int PARTIALLY_ENDED = 3">PARTIALLY_ENDED</a> case can be handled more explicitly.
</p><pre xmlns="" class="programlisting"><code>Coordination c = coordinator.begin("work",0);
try {
doWork();
} catch( Excption e ) {
c.fail(e);
} finally {
try {
c.end();
} catch( CoordinationException e ) {
if ( e.getType() == CoordinationException.PARTIALLY_ENDED) {
// limbo!
...
}
}
}</code></pre></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69498"></a><span xmlns="" class="number">130.2.6</span> Locking
</h3>
</div>
</div>
</div>
<p>To participate in a Coordination and receive callbacks a
collaborator must add a <code class="code">Participant</code> object to the
Coordination. The <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.addParticipant-Participant-" title="130.5.2.4 public void addParticipant(Participant participant)">addParticipant(Participant)</a> method blocks if the given
<code class="code">Participant</code> object is already used in another Coordination.
This blocking facility can be used to implement a number of simple
locking schemes that can simplify maintaining state in a concurrent
environment.
</p>
<p>Using the <code class="code">Participant</code> object as the key for the lock
makes it simple to do course grained locking. For example, a service
implementation could use the service object as a lock, effectively
serializing access to this service when it is used in a Coordination.
Coarse grained locking allows all the state to be maintained in the
coarse object and not having to worry about multiplexing simultaneous
requests. The following code uses the coarse locking pattern because the
collaborator implements the <code class="code">Participant</code> interface
itself:
</p><pre xmlns="" class="programlisting"><code>public class Collaborator implements Participant{
public void doWork(Coordination coordination ) {
...
coordination.addParticipant(this);
}
public void ended(Coordination c) { ... }
public void failed(Coordination c) { ... }
}</code></pre><p>The simplicity of the coarse grained locking is at the expense of
lower performance because tasks are serialized even if it would have no
contention. Locks can therefore also be made more fine grained, allowing
more concurrency. In the extreme case, creating a new object for each
participation makes it possible to never lock. For example, the
following code never locks because it always creates a new object for
the Participant:
</p><pre xmlns="" class="programlisting"><code> public void doWork(Coordination coordination){
final State state = ...
coordination.addParticipant(
new Participant() {
public void ended(Coordination c) { state ... }
public void failed(Coordination c) { state ...}
} ); }</code></pre></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69525"></a><span xmlns="" class="number">130.2.7</span> Failing
</h3>
</div>
</div>
</div>
<p>Any collaborator can fail an ongoing Coordination by calling the
<a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.fail-Throwable-" title="130.5.2.7 public boolean fail(Throwable cause)">fail(Throwable)</a> method, the Throwable parameter must not be
<code class="code">null</code>. When the Coordination has already terminated then
this is a no-op. The Coordinator service has a convenience method that
fails the current Coordination if present. The <code class="code">fail</code> methods
return a boolean that is <code class="code">true</code> when the method call causes
the termination of the Coordination, in all other cases it is
<code class="code">false</code>.
</p>
<p>Failing a Coordination will immediately perform the callbacks and
reject any additional Participants by throwing an <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.ALREADY_ENDED" title="130.5.3.1 public static final int ALREADY_ENDED = 4">ALREADY_ENDED</a> Coordination Exception. The asynchronous nature
of the fail method implies that it is possible to have been called even
before the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.addParticipant-Participant-" title="130.5.2.4 public void addParticipant(Participant participant)">addParticipant(Participant)</a> method has returned. Anybody that has the
Coordination object can check the failed state with the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.getFailure--" title="130.5.2.10 public Throwable getFailure()">getFailure()</a> method.
</p>
<p>In general, the best and most robust strategy to handle failures
is to throw an Exception from the collaborator, allowing the initiator
to catch the exception and properly fail the Coordination.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69554"></a><span xmlns="" class="number">130.2.8</span> Time-out
</h3>
</div>
</div>
</div>
<p>The time-out is specified in the Coordinator <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordinator.create-String-long-" title="130.5.5.3 public Coordination create(String name, long timeMillis)">create(String,long)</a> or <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordinator.begin-String-long-" title="130.5.5.2 public Coordination begin(String name, long timeMillis)">begin(String,long)</a> methods. A time-out of zero is indefinite,
otherwise the time-out specifies the number of milliseconds the
Coordination can take to terminate. A given time-out can be extended
with the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.extendTimeout-long-" title="130.5.2.6 public long extendTimeout(long timeMillis)">extendTimeout(long)</a> method. This method will add an additional
time-out to the existing deadline if a prior deadline was set. For
example, the following code extends the time-out with 5 seconds whenever
a message must be sent to a remote address:
</p><pre xmlns="" class="programlisting"><code>Object sendMessage(Message m) {
Coordination c = coordinator.peek();
Address a = m.getDestination();
if ( c != null && a.isRemote() ) {
c.extendTimeout(5000);
}
return sendMessage0(m);
}</code></pre><p>Applications should not rely on the exact time-out of the
Coordination and only use it as a safety function against deadlocks and
hanging collaborators.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69569"></a><span xmlns="" class="number">130.2.9</span> Joining
</h3>
</div>
</div>
</div>
<p>When a Coordination is terminated it is not yet completely
finished, the callback to the Participants happens after the atomic
termination. In certain cases it is necessary to ensure that a method
does not progress until all the participants have been notified. It is
therefore possible to wait for the Coordination to completely finish
with the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.join-long-" title="130.5.2.17 public void join(long timeMillis) throws InterruptedException">join(long)</a> method. This method can have a time-out. For
example:
</p><pre xmlns="" class="programlisting"><code>void collaborate( final Coordination c ) {
doWork();
Thread t = new Thread() {
public void run(){
try {
c.join(0);
... // really terminated here, all participantscalled back
} catch( Exception e) { ... }
}
};
t.start();
}</code></pre></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69578"></a><span xmlns="" class="number">130.2.10</span> Variables
</h3>
</div>
</div>
</div>
<p>A Participant is likely to have to maintain state that is
particular for the collaboration. This state is usually needed in the
<code class="code">ended</code> method to properly finalize the work. In general, the
best place to store this state is in the <code class="code">Participant</code> object
itself, inner classes and final variables are a good technique for
storing the state. However, the state can also be stored in a
Coordination <span class="emphasis"><em>variable</em></span>. Each Coordination has a
private set of variables that can be obtained with the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.getVariables--" title="130.5.2.15 public Map<Class<?>, Object> getVariables()">getVariables()</a> method. The resulting map takes a class as the
key and returns an Object. The map is not synchronized, any changes to
the map must be synchronized on the returned Map object to ensure the
visibility of the changes to other threads. The class used for the key
is not related to the returned type, it is a <code class="code">Class</code> object
to provide a convenient namespace.
</p>
<p>The following example shows how the state can be stored with
variables.
</p><pre xmlns="" class="programlisting"><code>public void doWork(Coordination coordination){
Map<Class<?>,Object> map = coordination.getVariables();
synchronized(map) {
State state = (State) map.get( SharedWorker.class );
if ( state == null ) {
state = new State(this);
map.put( state );
... do initial work
}
}
... do other work
coordination.addParticipant( this );
}
public void ended(Coordination c) {
Map<Class<?>,Object> map = coordination.getVariables();
synchronized(map) {
State state = (State) map.get( SharedWorker.class );
.. finalize
}
}
public void failed(Coordination c) {
Map<Class<?>,Object> map = coordination.getVariables();
synchronized(map) {
State state = (State) map.get( SharedWorker.class );
.. finalize
}
}</code></pre></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69601"></a><span xmlns="" class="number">130.2.11</span> Optimizing Example
</h3>
</div>
</div>
</div>
<p>For example, a web based system has a charge service:</p><pre xmlns="" class="programlisting"><code>public interface Charge {
void charge( String reason, int amount );
}</code></pre><p>This service is used throughout the system for charging the tasks
the system performs. Each servlet request can actually create multiple
Charge Data Records (CDR). For this reason, a Coordination is started
before the page is constructed. Each part of the page that has an
associated cost must create a CDR. There are the following issues at
stake:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>Charging should not take place when failing, and</p>
</li>
<li class="listitem">
<p>Performance can be optimized to only persist the CDRs once,
and
</p>
</li>
<li class="listitem">
<p>The user must be passed to the Charge service.</p>
</li>
</ul>
</div>
<p>To begin with the request code:</p><pre xmlns="" class="programlisting"><code>public void doGet(HttpServletRequest rq, HttpServletResponsersp) {
Coordination c = coordinator.begin("com.acme.request", 30000);
try {
Principal p = rq.getUserPrincipal();
Map<Class<?>,Object> map = c.getVariables();
map.put( Principal.class, p );
buildPage(rq,rsp);
} catch( Exception e ) { c.fail(e); }
finally { c.end(); }
}</code></pre><p>Each method that has a charge will call the Charge service. The
following code shows an implementation of this Charge service.
</p><pre xmlns="" class="programlisting"><code>public class ChargeImpl implements Charge,Participant {
final List<CDR> records = new ArrayList<CDR>();
public void charge( String reason, int amount ) {
Coordination c = coordinator.peek();
if ( c == null ) {
save( Arrays.asList( new CDR(null, reason, amount)));
} else {
Principal p = getPrincipal(c);
records.add( new CDR(p, reason, amount ) );
c.addParticipant( this );
}
}
Principal getPrincipal(Coordination c) {
if ( c == null )
return null;
Map<Class<?>,Object> map = c.getVariables();
synchronized(map) {
Principal p = (Principal) map.get( Principal.class );
return p != null ? p : getPrincipal(c.getEnclosingCoordination());
}
}
public void ended(Coordination c) {
save(records);
records.clear();
}
public void failed(Coordination c) {
records.clear();
}
void save(List<CDR> records) { ... }
}</code></pre></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69628"></a><span xmlns="" class="number">130.2.12</span> Security Example
</h3>
</div>
</div>
</div>
<p>The Coordination Permission is a filter based permission that is
asserted for many of the methods in the API, the bundle that is checked
is always the bundle that created the corresponding Coordination. For
example:
</p><pre xmlns="" class="programlisting"><code>ALLOW {
[ BundleSignerCondition "cn=ACME" ]
( CoordinationPermission "(signer=cn=ACME)" "*" )
}</code></pre><p>This example allows bundles signed by ACME to perform all
Coordination actions on Coordinations created by bundles signed by
ACME.
</p>
<p>The filter can also assert the name of the Coordination:</p><pre xmlns="" class="programlisting"><code>coordination.name</code></pre><p>It is therefore possible to create a name based protection scheme.
By denying all bundles except a select group through the use of a name
prefix, the use of Coordinations can be restricted to this select
group:
</p><pre xmlns="" class="programlisting"><code>DENY {
[ BundleSignerCondition "cn=ACME" "!" ]
( CoordinationPermission "(coordination.name=com.acme.*)""*" )
}
ALLOW {
( CoordinationPermission "(coordination.name=*)" "*" )
}</code></pre><p>If a bundle is not signed by ACME it will be denied the use of
Coordination names starting with <code class="code">com.acme.</code> though it will
be allowed to use any other name. This effectively enables only bundles
signed by ACME to create Coordinations with this name prefix.
</p>
</div>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h2 xmlns="http://www.w3.org/1999/xhtml" class="title" style="clear: both"><a xmlns="" class="anchor" id="i3151714"></a><span xmlns="" class="number">130.3</span> Coordinator Service
</h2>
</div>
</div>
</div>
<p>The Coordinator service is the entry point for the Coordination. It
provides the following functions:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p>Coordination creation</p>
</li>
<li class="listitem">
<p>Life cycle management of a Coordination</p>
</li>
<li class="listitem">
<p>Thread based Coordinations</p>
</li>
<li class="listitem">
<p>Introspection</p>
</li>
</ul>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69668"></a><span xmlns="" class="number">130.3.1</span> Coordination Creation
</h3>
</div>
</div>
</div>
<p>A <code class="code">Coordination</code> object is created by an
<span class="emphasis"><em>initiator</em></span>. An initiator can create a
<code class="code">Coordination</code> object with the Coordinator <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordinator.create-String-long-" title="130.5.5.3 public Coordination create(String name, long timeMillis)">create(String,long)</a> or <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordinator.begin-String-long-" title="130.5.5.2 public Coordination begin(String name, long timeMillis)">begin(String,long)</a> method. Each Coordination when created gets a
positive long identity that is available with <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.getId--" title="130.5.2.11 public long getId()">getId()</a>. Ids are a unique identifier for a specific
Coordinator service. The id is always increasing, that is, a
Coordination with a higher id is created later.
</p>
<p>The create methods specify the name of the Coordination. This name
is a security concept, see <a xmlns="" class="xref" href="service.coordinator.html#service.coordinator.security" title="130.4 Security">Security</a>, as well as used for debugging.
The coordination name must therefore conform to the same syntax as a
bundle symbolic name:
</p><pre xmlns="" class="programlisting"><code>coordination-name ::= symbolic-name // see <a class="xref" href="introduction.html#intro.core.release" title="1.2.1 OSGi Core Release 8">OSGi Core Release 8</a></code></pre><p>Passing a name that does not conform to this syntax must throw an
Illegal Argument Exception. There are no constraints on duplicates,
multiple different Coordinations can use the same name. The name of the
Coordination is available with the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.getName--" title="130.5.2.12 public String getName()">getName()</a> method.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69699"></a><span xmlns="" class="number">130.3.2</span> Adding Participants
</h3>
</div>
</div>
</div>
<p>The <code class="code">Coordination</code> object can be passed to
<span class="emphasis"><em>collaborators</em></span> as a parameter in a method call. Some
of these collaborators might be interested in
<span class="emphasis"><em>participating</em></span> in the given Coordination, they can
achieve this by adding a <code class="code">Participant</code> object to the
Coordination.
</p>
<p>A Participant is a collaborator that requires a callback after the
Coordination has been terminated, either when it ended or when it
failed. To participate, it must add a <code class="code">Participant</code> object to
a Coordination with the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.addParticipant-Participant-" title="130.5.2.4 public void addParticipant(Participant participant)">addParticipant(Participant)</a> method on Coordination. This method throws an
<a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.ALREADY_ENDED" title="130.5.3.1 public static final int ALREADY_ENDED = 4">ALREADY_ENDED</a> or <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.FAILED" title="130.5.3.4 public static final int FAILED = 2">FAILED</a> Coordination Exception when the Coordination has
been terminated.
</p>
<p>When a Participant is:</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><span class="emphasis"><em>Not in any Coordination</em></span> - Add it to the
given Coordination and return.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>In target Coordination</em></span> - Ignore,
participant is already present. A Participant can participate in the
same Coordination multiple times by calling <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.addParticipant-Participant-" title="130.5.2.4 public void addParticipant(Participant participant)">addParticipant(Participant)</a> but will only be called back once when the
Coordination is terminated. Its order must be defined by the first
addition.
</p>
</li>
<li class="listitem">
<p><span class="emphasis"><em>In another Coordination</em></span> - Lock until
after the other Coordination has notified all the Participants.
Implementations can detect deadlocks in certain cases and throw a
Coordination Exception if a dead lock exist, otherwise the deadlock
is solved when the Coordination times out.
</p>
</li>
</ul>
</div>
<p>Verifying if a Participant object is already in another
Coordination must use identity and not equality.
</p>
</div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69749"></a><span xmlns="" class="number">130.3.3</span> Active
</h3>
</div>
</div>
</div>
<p>A Coordination is active until it is
<span class="emphasis"><em>terminated</em></span>. A Coordination can terminate because it
is <span class="emphasis"><em>ended</em></span>, or it is <span class="emphasis"><em>failed</em></span>. The
following methods cause a termination:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<p><a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.end--" title="130.5.2.5 public void end()">end()</a> - A normal end. All participants that were
added before the end call are called back on their <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Participant.ended-Coordination-" title="130.5.6.1 public void ended(Coordination coordination) throws Exception">ended(Coordination)</a> method.
</p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.fail-Throwable-" title="130.5.2.7 public boolean fail(Throwable cause)">fail(Throwable)</a> - The Coordination has failed, this will
call back the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Participant.failed-Coordination-" title="130.5.6.2 public void failed(Coordination coordination) throws Exception">failed(Coordination)</a> method on the participants. This method can
be called by the Coordinator, the initiator, or any of the
collaborators. There are a number of failures that are built in to
the Coordinator. These failures use singleton Exception instances
defined in the <code class="code">Coordination</code> interface:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; ">
<li class="listitem">
<p><a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.TIMEOUT" title="130.5.2.3 public static final Exception TIMEOUT">TIMEOUT</a> - If the Coordination times out the
Coordination is failed with the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.TIMEOUT" title="130.5.2.3 public static final Exception TIMEOUT">TIMEOUT</a> exception instance in
Coordination.
</p>
</li>
<li class="listitem">
<p><a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.RELEASED" title="130.5.2.2 public static final Exception RELEASED">RELEASED</a> - If the Coordinator that created the
Coordination was unget, all Coordinations created by it will
fail with the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordination.RELEASED" title="130.5.2.2 public static final Exception RELEASED">RELEASED</a> exception.
</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<p>The state diagram for the Coordination is pictured in <a xmlns="" class="xref" href="service.coordinator.html#i3136697" title="Figure 130.4 Coordination state diagram">Figure <span class="number">130</span>.4</a>.
</p>
<div class="figure"><a xmlns="" class="anchor" id="i3136697"></a><p class="title"><strong>Figure <span xmlns="" class="number">130</span>.4 Coordination state diagram</strong></p>
<div class="figure-contents">
<div class="mediaobject" align="center"><img src="images/130-state-diagram.png" align="middle" width="559" height="140" alt="Coordination state diagram" /></div>
</div>
</div><br class="figure-break" /></div>
<div class="section">
<div xmlns="" class="titlepage">
<div>
<div>
<h3 xmlns="http://www.w3.org/1999/xhtml" class="title"><a xmlns="" class="anchor" id="d0e69802"></a><span xmlns="" class="number">130.3.4</span> Explicit and Implicit Models
</h3>
</div>
</div>
</div>
<p>The Coordinator supports two very different models of usage:
<span class="emphasis"><em>explicit</em></span> and <span class="emphasis"><em>implicit</em></span>. The
explicit model is when a Coordination is created and passed around as a
parameter. The second model is the implicit model where the Coordinator
maintains a thread local stack of Coordinations. Any collaborator can
then decide to use the top of the stack as the
<span class="emphasis"><em>current</em></span> Coordination. The <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordinator.peek--" title="130.5.5.7 public Coordination peek()">peek()</a> method provides access to the current
Coordination.
</p>
<p>The <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.Coordinator.begin-String-long-" title="130.5.5.2 public Coordination begin(String name, long timeMillis)">begin(String,long)</a> method creates a new Coordination and pushes
this on the stack, beginning an implicit Coordination. This is identical
to:
</p><pre xmlns="" class="programlisting"><code>coordinator.create("work",0).push();</code></pre><p>Once a Coordination is pushed on a stack it is from that moment on
associated with the current thread. A Coordination can only be pushed
once, the <a xmlns="" class="xref" href="service.coordinator.html#org.osgi.service.coordinator.CoordinationException.ALREADY_PUSHED" title="130.5.3.2 public static final int ALREADY_PUSHED = 5">ALREADY_PUSHED</a> Coordination Exception must be thrown when the