[java] lightweight messagechannel oplossing.

Pagina: 1
Acties:
  • 237 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Het laatste 3/4 jaar heb ik vaak de behoefte gehad aan een lightweight message channel oplossing en ik vind JMS te zwaar (vooral als je ook geen remoting nodig bent). De 1e paar keer heb ik de channel oplossing heel concreet opgezet voor 1 enkel systeem, maar voor het zoekplatform dat we aan het ontwikkelen zijn heb ik meteen maar iets zelfstandigs opgezet. En ik heb afgelopen week hier ook maar een zelfstandig project van gemaakt omdat ik het in de toekomst vaker wil gebruiken (ook binnen andere projecten) en dit project wil ik dus opensource gaan maken.

Hier kan je de voorlopige versie downloaden:
http://members.home.nl/peter-veentjer01/index.htm

Met messagechannels kun je heel eenvoudig een ontkoppeling aanbieden tussen verstuurder en ontvanger van berichten en hierdoor krijg je erg loosly coupled systemen -> hoge herbruikbaarheid. Verder zijn message systemen prachtig als je behoefte hebt aan asynchrone communicatie en eventueel het multithreaded maken van een applicatie.

Het lijkt me leuk als jullie eens naar het project zouden willen kijken en een flinke dosis kritiek willen uiten. En ik kan eventueel ook wel wat voorbeeldjes in elkaar zetten waarmee je de kracht van het systeem een beetje kunt inschatten. Het systeem is verder nog niet klaar.. er zijn nog genoeg dingen te doen :) Oa publishing bevalt me niet.. routing bevalt me niet in de huidige vorm.. en er moet nog wat gedaan worden aan exceptionhandeling...

ps:
de ideeen van channeling zijn niet van mij. Zelfs veel implementatie details zijn niet door mij bedacht (active maken van channels trouwens wel). Een gedeelte van de code is afgeleid van code van Doug Lea en zijn oude concurrency library (zoek maar eens op Channel/Puttable/Takeable). Helaas zit deze code niet meer in Java 5.0. Verder zijn er hele duidelijke verbanden te trekken naar java.io en de ontwikkelde classes van James Gosling (InputStream/OutputStream). En zoals je op de site kunt zien heeft Enterprise Integration Patterns er ook een erg grote invloed op.

Deze implementatie is dus alles behalve orgineel.. maar het is wel erg handig om nu eens een degelijke lightweight implementatie te kunnen gebruiken.

[ Voor 25% gewijzigd door Alarmnummer op 23-06-2005 14:44 ]


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
*kick*.. niemand zit aan de asynchrone communicatie of heeft behoefte aan een lightweight messaging oplossing? Niemand die een bepaald proces in meerdere stappen volledig beheersbaar moet uitvoeren?

*verwacht als die van bed komt een flinke lading kritiek* ;)

Acties:
  • 0 Henk 'm!

  • aex351
  • Registratie: Juni 2005
  • Laatst online: 08:57

aex351

I am the one

Ik vraag me af wat het is, echt duidelijk uitleg geef je er niet bij aangezien het erop lijkt dat je denkt dat iedereen dezelfde kennis heeft als jouw op dit gebied.

[ Voor 77% gewijzigd door aex351 op 24-06-2005 01:10 ]

< dit stukje webruimte is te huur >


Acties:
  • 0 Henk 'm!

  • dingstje
  • Registratie: Augustus 2002
  • Laatst online: 02-01-2024
Wat ik begrijp dat je hiermee zou kunnen doen:
Je krijgt een order binnen voor weet-ik-veel-wat.
Je zet die Order in een Message en verstuurt die.
Fabriek, Boekhouding, VoorraadBeheer etc. kunnen deze Message ontvangen en elk apart verwerken zonder dat de klasse die de order binnenkrijgt moet weten hoe Fabriek, Boekhouding en VoorraadBeheer werken.

Is dit ongeveer wat ik er mij bij moet voorstellen of ga ik hier compleet de mist in?

If you can't beat them, try harder


Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 19-07 01:17

Nick_S

++?????++ Out of Cheese Error

Als het echt messenging is, dan hoeft OrderVerwerking geeneens te weten, wie zijn berichten ontvangt.

Alarmnummer, ik heb nog niet naar jouw project gekeken, maar ik ga het zeker doen! Ik ben op dit moment bezig met Tibco messenging, maar dat wil je niet inzetten voor kleinere projecten. ($$$$$ ;)) Maar het hele idee er achter is wel goed.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • eenvande
  • Registratie: Augustus 2003
  • Laatst online: 24-05 09:29
@Alarmnummer:

Ik heb je gisteren een mail gestuurd, maar meng me ook maar even in deze discussie.

Ik ben erg geinteresseerd in jouw oplossing. Ik heb je code even snel bekeken, maar het is me niet duidelijk hoe ik deze code moet gebruiken. Je biedt aan om wat voorbeeldjes in elkaar zetten. Heel graag, want ik denk dat dit een hoop zal verduidelijken.

Jouw message channel oplossing doet mij trouwens een beetje aan Mule denken (mule.codehaus.org) of sla ik nu de plank volledig mis?

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
eenvande schreef op vrijdag 24 juni 2005 @ 09:27:
@Alarmnummer:

Ik heb je gisteren een mail gestuurd, maar meng me ook maar even in deze discussie.
Ik zal eens even kijken.

[edit]
Op mijn peter_veentjer at hotmail.com is niets binnengekomen. Zou je het nog een keer kunnen sturen?
Ik ben erg geinteresseerd in jouw oplossing. Ik heb je code even snel bekeken, maar het is me niet duidelijk hoe ik deze code moet gebruiken. Je biedt aan om wat voorbeeldjes in elkaar zetten. Heel graag, want ik denk dat dit een hoop zal verduidelijken.
Heel graag. Ik wil het dit weekend op sourceforge plaatsen en hulp kan zeker geen kwaad. Er zit een groot verschil tussen wat in elkaar zetten en er een bruikbaar algemeen project van te maken. Dus documentatie/tutorials kunnen zeker geen kwaad.
Jouw message channel oplossing doet mij trouwens een beetje aan Mule denken (mule.codehaus.org) of sla ik nu de plank volledig mis?
Ze hebben wel een bepaalde relatie. Ik geloof dat Mule een centrale plaats is waarin channels (services vaak) zich kunnen aanmelden. Maar bij Mule zit je veel meer op enterprise nivo te denken en dat is eigelijk niet direct het nivo waar ik aan zit te denken. Verder probeer ik geen JMS of webservices uit te vinden, maar gewoon een lightweight messaging solution dat gebruikt kan worden binnen 1 enkele jvm.

[ Voor 5% gewijzigd door Alarmnummer op 24-06-2005 11:03 ]


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
dingstje schreef op vrijdag 24 juni 2005 @ 08:50:
Wat ik begrijp dat je hiermee zou kunnen doen:
Je krijgt een order binnen voor weet-ik-veel-wat.
Je zet die Order in een Message en verstuurt die.
Fabriek, Boekhouding, VoorraadBeheer etc. kunnen deze Message ontvangen en elk apart verwerken zonder dat de klasse die de order binnenkrijgt moet weten hoe Fabriek, Boekhouding en VoorraadBeheer werken.

Is dit ongeveer wat ik er mij bij moet voorstellen of ga ik hier compleet de mist in?
Dit lijkt er heel veel op. Het voordeel aan messaging is dat de verstuurder van een bericht niet hoeft te weten naar wie hij het stuurt en de ontvanger van een bericht niet hoeft te weten wie het ontvang.

Stel dat je een autospuiterij hebt.. met een aantal stappen.. auto in ontvangst nemen.. schuren.. spuiten en lakken. en auto weer terug te geven.

Dan zou ik als volgt de workflow in elkaar kunnen zetten:

Begin->Schuren->Spuiten->Lakken->End

Maar stel dat ik tijdelijk controle wil inbouwen na het spuiten want er komen veel klachten:

Begin-Schuren->Spuiten->Controle->Lakken->End.

Of ik wil dat er 2 Schuurruimtes komen aangezien de huidige ruimte nogal klein is:

code:
1
2
3
      |->Schuren->|
Begin-|           |->Spuiten->Lakken->End
      |->Schuren->|


Zoals je ziet kun je naar wens de flow dus andersinrichten en dat geeft dus een enorme vrijheid. Je kan het bijna zien als loodgieter spelen. Je krijgt een hele zooi bochten, adapters, filters, stoppers, splitters en weet ik wat nog niet meer, en je kunt de wereld aan waterleidingen leggen met relatief eenvoudige componenten.

[ Voor 10% gewijzigd door Alarmnummer op 24-06-2005 10:30 ]


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Nick_S schreef op vrijdag 24 juni 2005 @ 09:14:
Als het echt messenging is, dan hoeft OrderVerwerking geeneens te weten, wie zijn berichten ontvangt.

Alarmnummer, ik heb nog niet naar jouw project gekeken, maar ik ga het zeker doen! Ik ben op dit moment bezig met Tibco messenging, maar dat wil je niet inzetten voor kleinere projecten. ($$$$$ ;)) Maar het hele idee er achter is wel goed.
Yep.. het concept is al vrij oud.. ik had alleen nog geen implementatie gezien die licht maar wel krachtig is (gemaakt kan worden). Het geheel is geinspireerd op Inversion of Control en dat geeft extreem minimalistische maar wel krachtige componenten.

Acties:
  • 0 Henk 'm!

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 19-07 01:17

Nick_S

++?????++ Out of Cheese Error

Net even proberen te openen in m'n editor, alleen ik zag dat je Java 1.5 gebruikt. Hmm, moet ik daar eerst maar eens naar gaan kijken. :)

Anyhow, als je opensource gaat, wil ik je wel helpen. M'n nick at Sourceforge is Nick_S (Wie heeft ooit bedacht, dat de korte versie van nickname nick moet zijn. :? )

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
aex351 schreef op vrijdag 24 juni 2005 @ 01:08:
Ik vraag me af wat het is, echt duidelijk uitleg geef je er niet bij aangezien het erop lijkt dat je denkt dat iedereen dezelfde kennis heeft als jouw op dit gebied.
Ik zal eens kijken of ik iets in elkaar kan zetten. Ik kan je wel literatuur aanraden Enterprise Integration Patterns : Designing, Building, and Deploying Messaging Solutions

Maar channels staat ik in veel andere boeken uitgelegd (zoek ook maar eens op Pipes en Filters)

Acties:
  • 0 Henk 'm!

  • zeroxcool
  • Registratie: Januari 2001
  • Laatst online: 08-07 22:55
Even lichtelijk offtopic, maar hoe zit het bijvoorbeeld met semaforen in Java? Die zijn misschien nog wel makkelijker te gebruiken voor het 'autospuiterij'-probleem dan deze channels oplossing?

Waren channels trouwens niet uitgevonden door Hoare, die ook quicksort bedacht had?

zeroxcool.net - curity.eu


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
ZeRoXcOoL schreef op vrijdag 24 juni 2005 @ 11:04:
Even lichtelijk offtopic, maar hoe zit het bijvoorbeeld met semaforen in Java?
Zit standaard in java 5.0
http://java.sun.com/j2se/...concurrent/Semaphore.html
Die zijn misschien nog wel makkelijker te gebruiken voor het 'autospuiterij'-probleem dan deze channels oplossing?
Semaforen kunnen gebruikt worden en dat kan hier ook gedaan worden. Er zijn bepaalde channels die met een BlockingQueue werken (bij output channels hoef je niet altijd te bufferen omdat je daar toch event driven aan het werk gaat.. iedere message die gepost wordt, zou eventueel direct verwerkt kunnen worden).

Deze BlockingQueues hebben zelf al de concurrency functionaliteit in zich die je ook met een Semaphore en een Queue kunt oplossen.

Verder ga jij nu automatisch uit van multithreaded systemen en dat is niet noodzakelijk bij deze aanpak. Ik ben namelijk ook een 'lightweight' messaging oplossing tegengekomen waarbij iedere channel zijn eigen thread(s) had en dat wil ik juist niet. Uiteraard is het wel extreem eenvoudig om een channel multithreaded te maken door de channel te verpakken in een ActiveOutputChannel wrapper.. Je kunt dus erg eenvoudig multithreaded werken, maar je zit er zeker niet aan vast.
Waren channels trouwens niet uitgevonden door Hoare, die ook quicksort bedacht had?
Dat zou best kunnen. Het is al een oud concept.. in de unix wereld wordt het al heel lang toegepast.

[ Voor 31% gewijzigd door Alarmnummer op 24-06-2005 11:53 ]


Acties:
  • 0 Henk 'm!

  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Ziet er leuk uit, een lichtgewicht variant van allerlei enterprise oplossingen voor dit probleem. JMS is inderdaad een stuk zwaarder, maar dat wil je typisch ook gebruiken voor guaranteed delivery, asynchrone communicatie en daar spelen ook dingen als transactie management, throttling, enz. Ook voor de workflow problemen die beschreven worden zijn gigantische frameworks beschikbaar. Fantastisch voor serieuze bedrijfsapplicaties maar een kanon op een mug voor de wat kleinere problemen. Als je iets simpels wilt maken maar toch een bepaalde flexibiliteit wilt hebben dan lijkt me dit een betere dosering.

Nu nog een Spring template... ;)

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Je bedoelt asynchrone remote communicatie neem ik aan. Channels zijn net zoals JMS dat is een voorbeeld van asynchrone communicatie.. mijn implementatie niet meer of minder dan JMS.
en daar spelen ook dingen als transactie management, throttling
Check de ActiveOuptutChannel :)

Je kunt door een implementatie van de BlockingExecutor (bv de blockingthreadpoolexecutor) veel meer controle krijgen over de threads dan je bij JMS dat ooit zou kunnen. Je kunt werkelijk iedere eigenschap instellen (priorities/threadcount etc), maar ook allerlei blocking eigenschappen kan je instellen door aan de BlockingExecutor weer een implementatie van de BlockingQueue mee te geven. Je kan kan een limit op het aantal elementen in de queue plaatsen, of een priorityblockingqueue meegeven als je wilt dat er 'voorkeurs' berichten zijn die eerder afgehandeld moeten worden.

Verkijk je niet op deze eenvoudige api.. je kunt er extreem krachtige toepassingen mee maken.
, enz. Ook voor de workflow problemen die beschreven worden zijn gigantische frameworks beschikbaar. Fantastisch voor serieuze bedrijfsapplicaties maar een kanon op een mug voor de wat kleinere problemen. Als je iets simpels wilt maken maar toch een bepaalde flexibiliteit wilt hebben dan lijkt me dit een betere dosering.
Precies.. als ik gebruik wil maken van channels maar de rest ben ik niet nodig, dan ben ik imho te veel werk aan het verzetten als ik met jms aan de slag ga + de oplossing wordt er ook niet bepaald duidelijker op.
Nu nog een Spring template... ;)
Niets ervan ;) Ik assisteer wat met de Lucene integratie met Spring en ze zijn veel te veel Spring minded.. allerlei afhankelijkheden naar Spring terwijl dat absoluut niet nodig is.

Trouwens een voorbeeldje van hoe ik channel toepas binnen Spring:
code:
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
    <bean id="crawler"
        class="com.jph.lucene.adoc.crawler.DirMappingTwoWayCrawler">

        <constructor-arg index="0">
            <bean class="com.jph.lucene.crawlers.SimpleCrawlerId">
                <constructor-arg index="0" value="standaard"/>
            </bean>
        </constructor-arg>

        <constructor-arg index="1" ref="index"/>
        <constructor-arg index="2" ref="docConverter"/>
        <constructor-arg index="3" ref="normalCrawlBeginPoint"/>
        <constructor-arg index="4" ref="deleteChannelBeginPoint"/>
        <constructor-arg index="5" ref="dirMappingRepository"/>
    </bean>

    <bean id="processingMap"
        class="org.jph.channel.StdProcessingMap"/>

    <bean id="deleteQueue"
        class="java.util.concurrent.LinkedBlockingQueue">
        <constructor-arg index="0" value="50000"/>
    </bean>

    <bean id="deleteChannelBeginPoint"
        class="org.jph.channel.active.StdActiveOuputChannel">

        <constructor-arg index="0">
            <bean
                class="org.jph.concurrent.BlockingThreadPoolExecutor"
                destroy-method="shutdown">
                <!-- core pool size -->
                <constructor-arg index="0" value="1"/>
                <!-- max pool size -->
                <constructor-arg index="1" value="1"/>
                <!-- die-time -->
                <constructor-arg index="2" value="5000"/>
                <!-- de tijdeenheid waarmee deze executorservice gaat werken -->
                <constructor-arg index="3" ref="java.util.concurrent.TimeUnit.MILLISECONDS"/>
                <!-- de queue die gebruikt wordt om taken in op te slaan -->
                <constructor-arg index="4" ref="retrieveOrCreateDocumentQueue"/>
                <!--
                    - de threadfactory die deze executorservice gebruikt om threads voor de threadpool
                    - aan te maken.
                     -->
                <constructor-arg index="5">
                    <bean class="org.jph.concurrent.StdThreadFactory">
                        <!-- priority -->
                        <constructor-arg index="0" value="1"/>

                        <!-- De naam van ThreadGroup waar de Threads onder vallen -->
                        <constructor-arg index="1" value="deleteQueue"/>
                    </bean>
                </constructor-arg>
            </bean>
        </constructor-arg>

        <constructor-arg index="1">
            <bean class="com.jph.lucene.adoc.standard.DeleteChannel">
                <constructor-arg index="0" ref="indexUpdater"/>
                <constructor-arg index="1" ref="pnlDocumentIndexReaderProvider"/>
                <constructor-arg index="2" ref="processingMap"/>
            </bean>
        </constructor-arg>
    </bean>

    <bean id="normalCrawlBeginPoint"
        class="anchormen.pnl.search.NormalCrawlStartOutputChannel">

        <constructor-arg index="0" ref="retrieveOrCreateDocumentChannel"/>
        <constructor-arg index="1" ref="processingMap"/>
    </bean>

    <bean id="retrieveOrCreateDocumentQueue"
        class="java.util.concurrent.LinkedBlockingQueue">
        <constructor-arg index="0" value="500000"/>
    </bean>

    <bean id="loadAndAnalyzeContentQueue"
        class="java.util.concurrent.LinkedBlockingQueue">
        <constructor-arg index="0" value="5000"/>
    </bean>

    <bean id="metadataAddingQueue"
        class="java.util.concurrent.LinkedBlockingQueue">
        <constructor-arg index="0" value="5000"/>
    </bean>

    <bean id="retrieveOrCreateDocumentChannel"
        class="org.jph.channel.active.StdActiveOuputChannel">

        <constructor-arg index="0">
            <bean
                class="org.jph.concurrent.BlockingThreadPoolExecutor"
                destroy-method="shutdown">
                <!-- core pool size -->
                <constructor-arg index="0" value="1"/>
                <!-- max pool size -->
                <constructor-arg index="1" value="1"/>
                <!-- die-time -->
                <constructor-arg index="2" value="5000"/>
                <!-- de tijdeenheid waarmee deze executorservice gaat werken -->
                <constructor-arg index="3" ref="java.util.concurrent.TimeUnit.MILLISECONDS"/>
                <!-- de queue die gebruikt wordt om taken in op te slaan -->
                <constructor-arg index="4" ref="retrieveOrCreateDocumentQueue"/>

                <constructor-arg index="5">
                    <bean class="org.jph.concurrent.StdThreadFactory">
                        <!-- priority -->
                        <constructor-arg index="0" value="1"/>

                        <!-- De naam van ThreadGroup waar de Threads onder vallen -->
                        <constructor-arg index="1" value="retrieveOrCreateDocument"/>
                    </bean>
                </constructor-arg>
            </bean>
        </constructor-arg>

        <constructor-arg index="1">
            <bean class="org.jph.channel.process.StdProcessingOutputChannel">
                <constructor-arg index="0" ref="loadAndAnalyzeContentChannel"/>

                <constructor-arg index="1">
                    <bean class="anchormen.pnl.search.RetrieveOrCreateDocumentMsgProcessor">
                        <constructor-arg index="0" ref="pnlDocumentIndexReaderProvider"/>
                        <constructor-arg index="1" ref="idFactory"/>
                    </bean>
                </constructor-arg>
            </bean>
        </constructor-arg>
    </bean>


    <bean id="loadAndAnalyzeContentChannel"
        class="org.jph.channel.active.StdActiveOuputChannel">

        <constructor-arg index="0">
            <bean class="org.jph.concurrent.BlockingThreadPoolExecutor"
                destroy-method="shutdown">
                <!-- core pool size -->
                <constructor-arg index="0" value="2"/>
                <!-- max pool size -->
                <constructor-arg index="1" value="6"/>
                <!-- die-time -->
                <constructor-arg index="2" value="5000"/>
                <!-- de tijdeenheid waarmee deze executorservice gaat werken -->
                <constructor-arg index="3" ref="java.util.concurrent.TimeUnit.MILLISECONDS"/>
                <!-- de queue die gebruikt wordt om taken in op te slaan -->
                <constructor-arg index="4" ref="loadAndAnalyzeContentQueue"/>

                <constructor-arg index="5">
                    <bean class="org.jph.concurrent.StdThreadFactory">
                        <!-- priority -->
                        <constructor-arg index="0" value="1"/>
                        <!-- De naam van ThreadGroup waar de Threads onder vallen -->
                        <constructor-arg index="1" value="loadersAndAnalyzers"/>
                    </bean>
                </constructor-arg>
            </bean>
        </constructor-arg>

        <constructor-arg index="1">
            <bean class="org.jph.channel.process.StdProcessingOutputChannel">
                <constructor-arg index="0" ref="metadataAddingChannel"/>

                <constructor-arg index="1">
                    <bean class="anchormen.pnl.search.LoadAndAnalyzeContentMsgProcessor">
                        <constructor-arg index="0" ref="dirMappingRepository"/>
                    </bean>
                </constructor-arg>
            </bean>
        </constructor-arg>
    </bean>

    <bean id="metadataAddingChannel"
        class="org.jph.channel.active.StdActiveOuputChannel">

        <constructor-arg index="0">
            <bean
                class="org.jph.concurrent.BlockingThreadPoolExecutor"
                destroy-method="shutdown">

                <!-- core pool size -->
                <constructor-arg index="0" value="1"/>
                <!-- max pool size -->
                <constructor-arg index="1" value="1"/>
                <!-- die-time -->
                <constructor-arg index="2" value="5000"/>
                <!-- de tijdeenheid waarmee deze executorservice gaat werken -->
                <constructor-arg index="3" ref="java.util.concurrent.TimeUnit.MILLISECONDS"/>
                <!-- de queue die gebruikt wordt om taken in op te slaan -->
                <constructor-arg index="4" ref="metadataAddingQueue"/>
                <!--
                - de threadfactory die deze executorservice gebruikt om threads voor de threadpool
                - aan te maken.
                 -->
                <constructor-arg index="5">
                    <bean class="org.jph.concurrent.StdThreadFactory">
                        <!-- priority -->
                        <constructor-arg index="0" value="1"/>
                        <!-- De naam van ThreadGroup waar de Threads onder vallen -->
                        <constructor-arg index="1" value="analyzers"/>
                    </bean>
                </constructor-arg>
            </bean>
        </constructor-arg>

        <constructor-arg index="1">
            <bean class="org.jph.channel.process.StdProcessingOutputChannel">
                <constructor-arg index="0" ref="writingEndPoint"/>

                <constructor-arg index="1">
                    <bean class="anchormen.pnl.search.MetadataAddingMsgProcessor">
                        <constructor-arg index="0" ref="pnlManager"/>
                    </bean>
                </constructor-arg>
            </bean>
        </constructor-arg>
    </bean>

    <bean id="writingEndPoint"
        class="anchormen.pnl.search.WritingOutputChannel">

        <constructor-arg index="0" ref="indexUpdater"/>
    </bean>


Kijk maar eens naar de 'loadAndAnalyzeContentChannel' en zie hoe ik de channel active heb gemaakt.

[ Voor 43% gewijzigd door Alarmnummer op 24-06-2005 20:47 ]


Acties:
  • 0 Henk 'm!

Anoniem: 128124

Je vraagt om kritiek, ik veronderstel positieve en opbouwende. An sich heb ik er niet zoveel op aan te merken, het ziet er goed doordacht uit en elke initiatief in deze richting kan ik alleen maar waarderen. Wat ik zonder er al te veel tijd in te steken erover kan zeggen is:
  • Presentatie van project en code: je moet ervoor zorgen dat je binnen 5 minuten iemand ervan overtuigt dat het de moeite waard is om twee en een half uur tijd te investeren om de details te leren kennen
  • Kijk bijvoorbeeld eens naar SWT Snippets.
  • Besteed aandacht aan JavaDoc: is code in het Engels, dan ook JavaDoc.
  • Schrijf een aantal posts in een weblog; goede artikelen met praktijkvoorbeelden en uitwerkingen ter illustratie. Heb jij een weblog? Ik zou me graag aanmelden.
  • Misschien dat je je met Java 5 een beetje uit de markt prijst. Niet zozeer qua nieuwigheid of kennisniveau, maar meer met het oog op trage invoering ervan bij bedrijven waarvoor ik - en ik neem aan anderen met mij - code schrijven.
Ik zou zeggen: ga vooral door!

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Anoniem: 128124 schreef op vrijdag 24 juni 2005 @ 20:43:
Je vraagt om kritiek, ik veronderstel positieve en opbouwende.
Ik kan ook met negatieve en afkrakende kritiek (mits goed beargumenteerd) omgaan. Voordeel aan negatieve kritiek is dat het eerlijk is en dat mensen het onderste uit de kan halen om iets onderuit te halen.
An sich heb ik er niet zoveel op aan te merken, het ziet er goed doordacht uit en elke initiatief in deze richting kan ik alleen maar waarderen. Wat ik zonder er al te veel tijd in te steken erover kan zeggen is:

[list]
• Presentatie van project en code: je moet ervoor zorgen dat je binnen 5 minuten iemand ervan overtuigt dat het de moeite waard is om twee en een half uur tijd te investeren om de details te leren kennen
Helemaal mee eens. Slechte presentatie -> dan zal het wel slechte software zijn. Ik als techneut betrap me daar ook iedere keer op.
• Besteed aandacht aan JavaDoc: is code in het Engels, dan ook JavaDoc.
Ook mee eens. Helaas is het schrijven van non-code niet mijn sterkste punt. Maar er moet zeker meer aandacht aan geschonken worden.. Het project is ook nog lang niet klaar, ik heb het zelfs nog niet eens 'officieel' opensource gemaakt.
• Schrijf een aantal posts in een weblog; goede artikelen met praktijkvoorbeelden en uitwerkingen ter illustratie. Heb jij een weblog? Ik zou me graag aanmelden.
Ik heb nog geen weblog. Staat al een tijd op mijn programma.. maar is er nog niet echt van gekomen. Te veel dingen te doen.. te veel dingen te lezen/leren.
• Misschien dat je je met Java 5 een beetje uit de markt prijst. Niet zozeer qua nieuwigheid of kennisniveau, maar meer met het oog op trage invoering ervan bij bedrijven waarvoor ik - en ik neem aan anderen met mij - code schrijven.
Dat is idd wel een punt. Misschien dat ik de jars naar 1.4 kan compileren en dat ik van de activechannels ook een 1.4 backport kan maken zodat je het onder 5.0 en 1.4 kunt gebruiken. Maar moet eerlijk toegeven dat dit nog niet erg hoog op mijn lijst staat.

Bedankt voor je commentaar :)

Acties:
  • 0 Henk 'm!

  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Ik had inderdaad al gezien dat je volgens IoC aan het werken was, waardoor je eigenlijk geen Spring specifieke dingen meer nodig hebt. Jouw Spring config file laat dit goed zien. :) Jammer alleen dat die constructor parameters niet named kunnen zijn, die nummertjes zijn niet echt duidelijk in een config file.

Ik bedoel communicatie inderdaad als interactie tussen systemen, en geen asynchrone verwerking binnen de applicatie. Ik zou zeker sceptisch zijn om JMS voor asynchrone verwerking in te zetten.

Met een threadpool kun je qua throttling wel een eind komen, in JMS kan dit echter wel wat uitgebreider zijn. Ik ben wel benieuwd of/hoe transactiemanagement geregeld is zodra je naar een andere thread gaat in de code. Dus bijvoorbeeld Object(nieuwe transactie) -> channel -> Object(bewerken) -> channel -> Object(transactie commit). Verhuist de transactie dan mee?

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
misfire schreef op zaterdag 25 juni 2005 @ 19:31:
Met een threadpool kun je qua throttling wel een eind komen, in JMS kan dit echter wel wat uitgebreider zijn.
Mijn kennis van JMS kan nog een heel stuk beter. Wat kan JMS wat je met de extreem ruime implementatie mogelijkheden van een interface ( bv BlockingExecutor) niet kunt? En als je zelfs van de BlockingExecutor af wilt kan dat door zelf een active-channel ontwerp te maken (die de Output/IntputChannel interface moet implementeren.. maar verder ook niet).

voor de anderen:
deze implementatie gaat geen concurrent worden van JMS. Deze implementatie valt in de lichte categorie.. op plekken waar je bv totaal geen remoting en dat soort zaken nodig bent maar wel via channels wilt werken. Het is dus absoluut niet mijn bedoeling om JMS na te gaan bouwen of alle features van JMS hierin te gaan plaatsen.
Ik ben wel benieuwd of/hoe transactiemanagement geregeld is zodra je naar een andere thread gaat in de code. Dus bijvoorbeeld Object(nieuwe transactie) -> channel -> Object(bewerken) -> channel -> Object(transactie commit). Verhuist de transactie dan mee?
Daar moet ik ook nog even heel goed over na gaan denken B)

[ Voor 38% gewijzigd door Alarmnummer op 25-06-2005 20:22 ]


Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 20-05 21:31
Hoewel het hier natuurlijk gaat om een specificieke implementatie (java & lightweight), vraag ik me af (zonder jouw werk overigens op een al te diep niveau ontleed te hebben), hoe jou aanpak overeenkomt met projecten als:

• The Reo Language
The Reo language represents a paradigm for composition of software components based on the notion of mobile channels. Reo enforces a channel-based coordination model that defines how application designers can build complex coordinators, called connectors, out of simpler ones. Reo features include, among others, loose coupling among components, support for distribution and mobility of heterogeneous components, coordination from the outside (i.e., by third parties), and a sound formal base.
Zie http://web.cs.uni-bonn.de/I/baier/papers/ABdBRS05_COORD.pd en http://www.liacs.nl/edu/bsc_projects.html

• The Job Description Language
Zie http://www.liacs.nl/~jdawn/screenshots.html
en documentatie:
http://www.liacs.nl/~jdawn/jdawn_presentation.pdf en http://www.liacs.nl/~jdawn/jdawn_thesis.pdf

Het 2de project lijkt erg op Unix pipe & filters (wat jij ook al noemde in deze thread) maar dan in DAG topology ipv alleen een pipe-line (rechte lijn). In dit project worden de verbindingen tussen components beschreven door een XML document, waarbij een centrale controller de output uit de channels van het ene component 'neemt' en die aan de gekoppelde componenten 'geeft'. Zo te zien kunnen de componenten ook in code door statements gekoppeld worden, maar is de XML manier aan handige default. Het lijkt op een toepassing van IOC wat jij ook al noemde. Componenten zijn gewoon classen die een bepaalde interface implementeren.

• Click
Zie http://pdos.csail.mit.edu/click/doc/click.5.html

Ik heb hier nog het minste naar gekeken, maar het lijkt op weer een andere toepassing / implementatie van het zelfde concept: components en channels aan elkaar linken.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • Baron
  • Registratie: Juli 2000
  • Laatst online: 11-07 08:32
Heb je dit al eens bekeken?

Somnifugi

SomnifugiJMS is an implementation of JMS that works inside a single JVM to send JMS Messages between Threads. Somnifugi is particularly useful for isolating the awt Thread so that the user interface will stay lively, for decoupling calls to slower external resources such as database connections, and for speeding up implementations of generic JMS clients by placing decoupled JMS clients in the same JVM.

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Baron schreef op dinsdag 28 juni 2005 @ 08:43:
Heb je dit al eens bekeken?

Somnifugi

SomnifugiJMS is an implementation of JMS that works inside a single JVM to send JMS Messages between Threads. Somnifugi is particularly useful for isolating the awt Thread so that the user interface will stay lively, for decoupling calls to slower external resources such as database connections, and for speeding up implementations of generic JMS clients by placing decoupled JMS clients in the same JVM.
Ik zie het voordeel van zo`n lightweight JMS implementatie niet. Ze willen asynchroon en mutlithreaded kunnen werken maar dan zijn er veel betere oplossingen dan zo`n overkill oplossing waar je volgens mij alleen maar last van hebt. Als iemand een standaard implementatie zou gebruiken om dit te realiseren dan denk ik dat hij de verkeerde techniek gekozen heeft. Maar als ze zelf zo`n implementatie hebben gemaakt, dan denk ik dat zo hun tijd totaal hebben verkwist.

Er zijn ook genoeg alternatieven die je kunt gebruiken zoals de concurrency library van doug lea en die niet zoveel crap met zich meeslepen.

Ps:
Nogmaal. Ik probeer geen JMS na te bouwen. JMS heeft hele andere doelen dan mijn implementatie. En ik kies nog steeds JMS als ik eisen heb die overeen komen met wat JMS bied.

[ Voor 19% gewijzigd door Alarmnummer op 28-06-2005 09:38 ]


Acties:
  • 0 Henk 'm!

  • momania
  • Registratie: Mei 2000
  • Laatst online: 07:15

momania

iPhone 30! Bam!

Alarmnummer schreef op vrijdag 24 juni 2005 @ 20:54:

Ook mee eens. Helaas is het schrijven van non-code niet mijn sterkste punt. Maar er moet zeker meer aandacht aan geschonken worden.. Het project is ook nog lang niet klaar, ik heb het zelfs nog niet eens 'officieel' opensource gemaakt.
Ken je http://checkstyle.sourceforge.net/ al :?

Misschien is dat een mooi hulpmiddel voor je om tijdens het ontwikkelen, je javadocs al compleet te krijgen.

Je kan er iig een goede plugins krijgen voor verschillende IDE's, waarbij je zelf kan aangeven welke code conventions je gecontroleerd wilt hebben.

Ik vind het iig erg handig dat je gewoon een warning in je code ziet als er bijvoorbeeld nog javadocs missen. Je pakt het wat makkelijker op als je het direct ziet, ipv als je achteraf je javadocs leest en opmerkt dat je nog een hele boel mist.

Neem je whisky mee, is het te weinig... *zucht*


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
momania schreef op dinsdag 28 juni 2005 @ 09:38:
[...]

Ken je http://checkstyle.sourceforge.net/ al :?

Misschien is dat een mooi hulpmiddel voor je om tijdens het ontwikkelen, je javadocs al compleet te krijgen.
een goeie ide die doet dat al voor je. En het is niet zozeer dat de structuur van de javadoc het probleem is, maar de inhoud :) En er is geen tool die dat voor mij scrhijft.

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
flowerp schreef op zondag 26 juni 2005 @ 13:29:
Hoewel het hier natuurlijk gaat om een specificieke implementatie (java & lightweight), vraag ik me af (zonder jouw werk overigens op een al te diep niveau ontleed te hebben), hoe jou aanpak overeenkomt met projecten als:

..

Het 2de project lijkt erg op Unix pipe & filters (wat jij ook al noemde in deze thread) maar dan in DAG topology ipv alleen een pipe-line (rechte lijn).
Je kan met de Intput/OutputChannels iedere mogelijke graph in elkaar zetten die je maar nodig bent. Het stuk over publishers en routers moet nog verder uitgewerkt worden bij de channels, maar daarmee heb je dus al standaard channels waarmee je echt complexe channel-structuren in elkaar kunt zetten.
Zo te zien kunnen de componenten ook in code door statements gekoppeld worden, maar is de XML manier aan handige default.
Ik heb niets voor het XML gebeuren hoeven te doen hoor. Het is een voorbeeld hoe ik de objecten via Spring zou kunnen opbouwen. Maar het zo net zo goed in Pico of iets anders kunnen. En verder kan je het altijd nog doen in 'echte' java.

Acties:
  • 0 Henk 'm!

  • -FoX-
  • Registratie: Januari 2002
  • Niet online

-FoX-

Carpe Diem!

Alarmnummer schreef op dinsdag 28 juni 2005 @ 09:42:
[...]
een goeie ide die doet dat al voor je. En het is niet zozeer dat de structuur van de javadoc het probleem is, maar de inhoud :) En er is geen tool die dat voor mij scrhijft.
Deze keer heb je het wel serieus mis hoor :P !!
Er bestaat zelfs een hele goed tool voor dergelijke problemen op te lossen: Commentator :Y)

Verder denk ik dat er wel heel wat potentieel in dit project zit, ik volg het daarom ook.
Nogmaal. Ik probeer geen JMS na te bouwen. JMS heeft hele andere doelen dan mijn implementatie. En ik kies nog steeds JMS als ik eisen heb die overeen komen met wat JMS bied.
Akkoord, maar wanneer zou je dan wel voor JMS kiezen?

offtopic:
just you wait until I finish my book ;)

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
:D
Akkoord, maar wanneer zou je dan wel voor JMS kiezen?
Oa op het moment dat remoting belangrijk gaat worden. Stel dat ik meerdere systemen over verschillende vm`s aan wil sluiten op een andere systeem via messaging, dan zou ik JMS nemen. Wil je het binnen 1 vm houden en ben je op zoek naar een channel implementatie (zoals JMS dat ook is), dan zou ik ik kijken of mijn implementatie daar handig voor is. Ik moet verder nog kijken hoe transacties het beste in mijn implementatie gelijmd kunnen worden.

Op dit moment gebruik ik channels om componenten te kunnen ontkoppelen. Voor het searchengine platform (waar ik oa mee bezig ben) wil ik erg losgekoppelde componenten hebben omdat we het project breed willen kunnen inzetten. Je komt daarbij altijd rare eisen tegen en daar willen we goed op in kunnen spelen. Een van de manieren om dat te kunnen doen is een platform te maken die bestaat uit erg breed te configureren componenten (via ioc.. alle componenten zijn zelf miniframeworkjes). Maar ook tussen de componenten moeten weinig relaties bestaan, zodat ook een heel systeem vervangen kan worden (je zult altijd zien dat het voorkomt dat een kant en klaar component totaal niet past).

Asynchrone communicatie is voor mij de manier om systemen erg los gekoppeld te maken. Ik ga straks weer aan de slag met mijn prolog compiler en het is de bedoeling dat channels ingezet gaat worden voor het compilatie proces...

[ Voor 7% gewijzigd door Alarmnummer op 28-06-2005 12:07 ]


Acties:
  • 0 Henk 'm!

  • JaWi
  • Registratie: Maart 2003
  • Laatst online: 20-06 21:19

JaWi

maak het maar stuk hoor...

Okee; heb ook even de moeite genomen naar je code te kijken. Allereerst: ik zie wel potentie in het gebruik van je code voor een van m'n eigen projectjes waarbij af en toe wat asynchrone communicatie moet plaatsvinden. De implementatie is erg licht en eenvoudig te gebruiken (voor zover ik dat heb kunnen zien)...

Inhoudelijk heb ik ook wat opmerkingen:

• Je maakt hevig gebruik van generics voor je messages; maar nergens zie ik iets terugkomen van
wat precies een message zou moeten zijn (okee, da's natuurlijk 't doel van generics, maar ik vermoed dat er toch wel iets van een interface voor een message is?);
• Waar zijn de unit-tests?! :P De standaard implementaties van je interface vraagt natuurlijk om een aantal functionele testen (heeft geeft daarnaast gelijk een mooi code-voorbeeld);
• StdActiveInputChannel doet volgens mij niet wat je beoogt: hij heeft wel een Runnable implementatie, maar die wordt nergens gebruikt (of ik ben scheel);

Minder inhoudelijke zaken, maar meer op je code gericht:

• Vanwaar het hevige gebruik van excepties voor het controleren van je parameters? IMHO is dit een van de plaatsen waar asserts prima tot hun recht komen;
• Ik zag in ContentBasedRoutingOutputChannel dat je een iterator van receivers teruggeeft; dat lijkt mij niet zo handig als je je receivers meer dan eens wilt gebruiken; waarom geen (Unmodifiable)List (je doet het op meerdere plekken)?

Statistics are like bikinis. What they reveal is suggestive, but what they hide is vital.


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
JaWi schreef op dinsdag 28 juni 2005 @ 12:42:
Okee; heb ook even de moeite genomen naar je code te kijken. Allereerst: ik zie wel potentie in het gebruik van je code voor een van m'n eigen projectjes waarbij af en toe wat asynchrone communicatie moet plaatsvinden. De implementatie is erg licht en eenvoudig te gebruiken (voor zover ik dat heb kunnen zien)...
Cool.. mischien moet ik er gewoon cardware van maken ;) Wil je het gebruiken dan moet je een postkaart sturen ;)
Inhoudelijk heb ik ook wat opmerkingen:

• Je maakt hevig gebruik van generics voor je messages; maar nergens zie ik iets terugkomen van
wat precies een message zou moeten zijn (okee, da's natuurlijk 't doel van generics, maar ik vermoed dat er toch wel iets van een interface voor een message is?);
Nope :) geeft geen onnodige dependencies naar een message interface. (Is dus met opzet zo)
• Waar zijn de unit-tests?! :P De standaard implementaties van je interface vraagt natuurlijk om een aantal functionele testen (heeft geeft daarnaast gelijk een mooi code-voorbeeld);
Unit tests zitten nog in het project waar dit project dus in zat.
• StdActiveInputChannel doet volgens mij niet wat je beoogt: hij heeft wel een Runnable implementatie, maar die wordt nergens gebruikt (of ik ben scheel);
De InputChannel ben ik nog mee bezig. Staat geloof ik commentaar boven in.. Er zijn eerst wat problemen die ik uit moet dokteren Aan een input channel wordt getrokken om berichten op te halen en de inputchannel moet aan een andere input channel trekken om berichten op te halen. Stel dat ik een router heb met 2 trek-aan-mij-kanallen (dus halen berichten bij hem op). Een een van deze kanalen vraagt een bericht maar dat bericht is niet voor hem geschikt -> dan moet dat bericht gequeued worden zodat het andere kanaal die later op kan halen. Ik wil hier even goed over nadenken welke consequenties dit allemaal heeft. Ik wil sowieso nog even nadenken of ik hiermee wel op de juiste manier bezig ben.
• Vanwaar het hevige gebruik van excepties voor het controleren van je parameters? IMHO is dit een van de plaatsen waar asserts prima tot hun recht komen;
Ik ben aanhanger van de defensieve stijl van programmeren: als het tot zover is gelukt, dan moet het wel goed zijn gegaan. Maar assers mogen niet gebruikt worden voor publieke methodes om dit te realiseren. Check de documentatie maar eens en check de code van java.util.concurrent en het collectionframework maar eens. Hier gebeurt het ook goed in.
• Ik zag in ContentBasedRoutingOutputChannel dat je een iterator van receivers teruggeeft; dat lijkt mij niet zo handig als je je receivers meer dan eens wilt gebruiken; waarom geen (Unmodifiable)List (je doet het op meerdere plekken)?
Dit snap ik niet helemaal en verder moet er nog wat aan structuren gebeuren. Ik ga zometeen werken met immutable lijsten en replace-on-write. Hierdoor heb minder te maken met concurrency problematiek (hier zitten nog een paar foutjes in)..

[ Voor 23% gewijzigd door Alarmnummer op 28-06-2005 14:19 ]


Acties:
  • 0 Henk 'm!

  • JaWi
  • Registratie: Maart 2003
  • Laatst online: 20-06 21:19

JaWi

maak het maar stuk hoor...

Alarmnummer schreef op dinsdag 28 juni 2005 @ 14:06:
Cool.. mischien moet ik er gewoon cardware van maken ;) Wil je het gebruiken dan moet je een postkaart sturen ;)
Okee, krijg jij een kaartje van me... :)
De InputChannel ben ik nog mee bezig. Staat geloof ik commentaar boven in.. Er zijn eerst wat problemen die ik uit moet dokteren Aan een input channel wordt getrokken om berichten op te halen en de inputchannel moet aan een andere input channel trekken om berichten op te halen. Stel dat ik een router heb met 2 trek-aan-mij-kanallen (dus halen berichten bij hem op). Een een van deze kanalen vraagt een bericht maar dat bericht is niet voor hem geschikt -> dan moet dat bericht gequeued worden zodat het andere kanaal die later op kan halen. Ik wil hier even goed over nadenken welke consequenties dit allemaal heeft. Ik wil sowieso nog even nadenken of ik hiermee wel op de juiste manier bezig ben.
Hmm, is het niet een beter idee om de router een kanaal alleen die berichten te geven die voor hem bestemd zijn? Bij jouw voorstel krijg je nl. nogal wat extra queueing overhead. Bijv, als je twee kanalen hebt, eentje met high-traffic, en eentje met low-traffic; de low-traffic krijgt af en toe een berichtje, maar zorgt wel iedere keer voor het opnieuw queuen van alle berichten die hij vanwege het high-traffic kanaal krijgt...
Ik ben aanhanger van de defensieve stijl van programmeren: als het tot zover is gelukt, dan moet het wel goed zijn gegaan. Maar assers mogen niet gebruikt worden voor publieke methodes om dit te realiseren. Check de documentatie maar eens en check de code van java.util.concurrent en het collectionframework maar eens. Hier gebeurt het ook goed in.
Defensief programmeren ben ik absoluut voor; maar ik denk dat we hier een verschil van (implementatie-)mening hebben. Ik zorg er meestal voor dat mijn methodes hun contract afdwingen middels asserts, maar dit is geheel off-topic en niet relevant voor deze topic...

Statistics are like bikinis. What they reveal is suggestive, but what they hide is vital.


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
JaWi schreef op dinsdag 28 juni 2005 @ 14:40:
[...]
Hmm, is het niet een beter idee om de router een kanaal alleen die berichten te geven die voor hem bestemd zijn?
Nee.. want de berichten zijn dan niet binnen :P En als die binnen is, dan ben je verantwoordelijk voor de afhandeling ervan (je mag het niet weggooien)
Bij jouw voorstel krijg je nl. nogal wat extra queueing overhead. Bijv, als je twee kanalen hebt, eentje met high-traffic, en eentje met low-traffic; de low-traffic krijgt af en toe een berichtje, maar zorgt wel iedere keer voor het opnieuw queuen van alle berichten die hij vanwege het high-traffic kanaal krijgt...
Dit is dus exact het probleem.
Defensief programmeren ben ik absoluut voor; maar ik denk dat we hier een verschil van (implementatie-)mening hebben. Ik zorg er meestal voor dat mijn methodes hun contract afdwingen middels asserts, maar dit is geheel off-topic en niet relevant voor deze topic...
Ik probeer me zoveel mogelijk in dit opzicht toch aan de standaard te houden en vind het niet zo`n fundamenteel probleem. Heb liever een goeie structuur + fouten (en hoe de fouten dan opgeworpen vind ik niet zo`n probleem).

[ Voor 10% gewijzigd door Alarmnummer op 28-06-2005 15:55 ]


Acties:
  • 0 Henk 'm!

Anoniem: 42145

Alarmnummer schreef op dinsdag 28 juni 2005 @ 09:50:
[...]
Je kan met de Intput/OutputChannels iedere mogelijke graph in elkaar zetten die je maar nodig bent.
Dat houdt dus automatisch in dat je cycles kunt creeeren. Hoe ga je hiermee om? Je filters zullen nu een stuk complexer moeten worden, en state moeten bijhouden. Simpel weg input accepten, bewerken, en output genereren (zoals in Unix) zal er dan niet mee bij zijn. Toch?

Btw, een ander systeem wat ook met dit principe werkt maar weer een TOTAAL andere toepassing heeft is max/msp.

Zie: http://www.cycling74.com/products/maxmsp.html

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Anoniem: 42145 schreef op donderdag 30 juni 2005 @ 12:00:
[...]
Dat houdt dus automatisch in dat je cycles kunt creeeren. Hoe ga je hiermee om?
Dat is niet mijn pakkie aan denk ik. Iemand die zo dom is om een cycle te maken is daar zelf verantwoordelijk voor. Dito voor deadlocks.

Voor een zoeksysteem heb ik intussen ook al een mooi stuk met routers in elkaar zitten: channels voor grote/complexe documenten en channels voor kleine documenten. Ideaal om er voor te zorgen dat grote documenten het systeem niet volledig blokkeren en dat kleine documenten altijd 'direct' geindexeerd kunnen worden. De router die plaatst het dus op de juiste kanaal ( die weer hun eigen eigen queues en eigen threadpools hebben ) en als ze klaar zijn plaatsen ze het weer op een gemeenschappelijk kanaal zodat het daadwerkelijk naar de index geschreven kan worden.

Ikzit er nog wel aan te denken om naast het blokkeren van de queue op size ook de queue te kunnen blokken op andere voorwaarden (bv de inhoud). Stel dat er in een queue 1000 documenten passen, en toevallig zitten er 1000 documenten in van iedere 1 mb. dan zit je op 1 gig. Ik wil dan de queue kunnen blokken op size (1000 documenten) maar ook op een andere voorwaarde (max 100mb). Ik zou wel een wrapper (ook een BlockingQueue) om een BlockingQueue kunnen plaatsen die deze functionaliteit toevoegt. Maar over de consequenties van deze aanpak moet ik nog goed nadenken.
Je filters zullen nu een stuk complexer moeten worden, en state moeten bijhouden. Simpel weg input accepten, bewerken, en output genereren (zoals in Unix) zal er dan niet mee bij zijn. Toch?
Als iemand wel een cycle erin wil hebben, dan moet hij dit zelf op zien te lossen. Het framework bied je de basis stenen en alles wat mist, moet je er zelf bij maken. Voorlopig zie ik nog geen reden om een oplossing te bedenken voor cycle (en ook eventueel daaruit volgende deadlock) problematiek.
Btw, een ander systeem wat ook met dit principe werkt maar weer een TOTAAL andere toepassing heeft is max/msp.

Zie: http://www.cycling74.com/products/maxmsp.html
Ik zal dat eens bekijken.

[ Voor 40% gewijzigd door Alarmnummer op 30-06-2005 12:22 ]


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Ik ben nu intussen uit de routing problematiek. Via een MessagePredicate (kan voor meerdere zaken gebruikt worden) kan een subscriber geregistreerd worden bij een publisher.

voorbeeld:
Ik heb voor een zoeksysteem behoefte om crawlberichten (voor files) de berichten te verdelen over een aantal channels. 1 channel voor kleine bestande, 1 channel voor middelgrote bestanden en 1 channel voor grote bestanden. Dit doe ik zodat het systeem niet verstopt raakt door grote bestanden. Hieronder staat een stukje (pseude) code hoe ik dit nu in elkaar kan zetten.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CrawlMsg{ File file}

class MaxSizePredicate implements MessagePredicate<CrawlMsg>{
      long maxSize;
      MaxSizePredicate(long maxSize){this.maxSize = maxSize;}
     
     boolean evaluate(CrawlMsg msg){msg.file.fileSize<=maxSize;}
}

//true is ervoor dat je stopt zo gauw een subscriber het bericht heeft geaccepteerd
RoutingOutputChannel<CrawlMsg> routingChannel = new StdRoutingOutputChannel<CrawlMsg>(true);
routingChannel.subscribe(new MaxSizePredicate(100000), kleineChannel);
routingChannel.subscribe(new MaxSizePredicate(1000000), middelGroteChannel);
routingChannel.subscribe(groteChannel);

[ Voor 8% gewijzigd door Alarmnummer op 02-07-2005 10:49 ]

Pagina: 1