|
|||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Class Summary | |
---|---|
AppenderBase | |
BidUpdateDispatcher | marshal events that represent changes to the active bids displayed in the stripchart. |
Dispatcher | Dispatchers marshall events and publish them via cometd. |
MockBayeux | |
MockBayeuxChannel | |
NewChartAppender | publishes actions announcing new price charts to cometd. |
NewChartDispatcher | marshalls events that announce the availability of
new price charts . |
PriceActionAppender | publishes actions describing bidding behavior to cometd |
PriceChangeAppender | publishes actions announcing new MarketMaker prices to cometd. |
PriceChangeDispatcher | marshalls events that represent new price levels . |
PrivateEventAppender | Uses log4j to dispatch events to individual endpoints rather than broadcasting them. |
PrivateEventDispatcher | marshalls private events and distributes them to a particular user via comet. |
TradeEventDispatcher | marshalls events that represent trades that have taken place. |
TransitionAppender | publishes actions representing Session state transitions to cometd. |
TransitionDispatcher | marshalls events that represent state transitions in the Session. |
This package allows Zocalo to publish significant events via Log4J
and cometd (an AJAX technology). The events
(in events
) are used to add information to the log,
to store records in the database, to update the strip chart showing bidding activity to experimental subjects, and
to notify the UI of significant events. Log4J provides a general framework for connecting together reports of events
that can be output in a variety of formats and piped dynamically without changing the call site.
There are two hierarchies here: Dispatchers
, and Appenders. The
Appenders are specializations of Log4J's AppenderSkeleton
.
Dispatchers marshall events and publish them via cometd.
The Log4J framework is used to distribute the actions to cometd, to Zocalo's own Log4J logs, and to produce records of transactions in the database for the prediction market. The Appenders provide the connection between Log4J and cometd by registering an interest in particular Log4J channels, and when events arrive, publishing them to cometd using the Dispatchers.
PriceActionAppender
is interested in trades and other changes in prices including new bids
(Bid
and Ask
), retracted bids
(OrderRemoval
and SelfDealing
), changes in the
best bid and ask (BestBid
, and
BestAsk
), and completed trades (Trade
). The
other Appender is TransitionAppender
, which is interested in
Transition
actions affecting experiments.
The Dispatchers marshall the events and send them on to cometd.
TradeEventDispatcher
deals with events representing trades that have taken place,
BidUpdateDispatcher
handles events that involve changing the active bids
displayed on the stripchart, and TransitionDispatcher
handles events that
represent state transitions in experiment sessions which have effects in the browser that go beyond the strip chart.
Event
) objects are created when something significant happens in the server.
Events are instances of subclasses of Action
, which extends
LoggingEvent
. This makes it possible for them to be handed directly to a
logger which causes them to be passed as an argument to the AppenderSkeleton's
append(LoggingEvent)
. method.
Log4j provides AppenderSkeleton, which is the prototype for Appenders that consume Events. Zocalo's Appenders format
the events and distribute them to Dispatchers
. The dispatchers
have a reference to a bayeux channel (Bayeux is a protocol that supports
AJAX-style browser intereactions.) The dispatchers can
marshall events and thereby publish them to AJAX. There's also a MockBayeux
and MockBayeuxChannel
that allows Zocalo to collect events internally when necessary.
Each Appender has one or more Dispatcher. The Appenders react to specific server-side events, and distribute them to their dispatchers. The dispatchers represent a particular channel distributing messages for a set of clients. This allows javascript in the browser to specify which set of events it wants to consume and assign a handler method in the browser to be invoked when a message of interest arrives.
Here are three example cases. PriceChange events are generated during experiments whenever there's a change is the set of bids in the book, and are used in the browser to trigger updating the candle chart displaying all the outstanding offers. (They are distinct from Trades, which only occur when an actual trade takes place, and cause a new historical price to be displayed, and the candle moved right.) IndividualTimingEvents are distributed directly to a particular user (a Judge) when a timer expires. In the browser, we can then disable the judge's inputbox for entering price estimates. This only affects one experiment subject. The third case is used to update price charts after a trade in a prediction market. It takes a significant amount of time to compute the price charts, so we have a separate thread generating them, and once the chart is ready, we send out an update to all the browsers viewing that market so they can request a new copy. Since this is a simple image refresh, Jetty can handle it in parallel with the continuing market activity.
The table shows the current events and how and where the code sets up the path they traverse. For each, we show
EXPERIMENTS | Book Price update (Exp) | Timing Events (Exp) | Trade Events (Exp) | Transition Events (Exp) |
---|---|---|---|---|
Purpose | Book Price update: modify candle and current bids and asks | Judge timed out | Trade took place: add a black dot | Experiment transitioned to the next phase |
Event | PriceAction created in recordTrade in BinaryMarketMaker or MultiMarketMaker after trade | created in TimerTask in Judge.getCutoffTimer() | PriceAction created in Binary, Unary, and MultiMarket, in record*Trade() | Transition is created in Session.logTransitionEvent() |
Appender | PriceActionAppender created in Session.initializeMarket() for bayeux and MockBayeux. | PrivateEventAppender created in Session.initializeMarket(). | PriceActionAppender created in Session.initializeMarket() for bayeux and MockBayeux. | TransitionAppender created in Session.initializeTransitionAppender(). |
Logger | PriceAction.class | IndividualTimingEvent.class | PriceAction.class | Transition.class |
callAppenders() | PriceAction.log() called in event constructor, which uses Logger(PriceAction.class) | in IndividualTimingEvent constructor logger.callAppenders(this); | PriceAction.log() called in event constructor, which uses Logger(PriceAction.class) | in Transition constructor |
Dispatcher | BidUpdateDispatcher created by PriceActionAppender | PrivateEventDispatcher created by PrivateEventAppender. PrivateEventDispatcher uses deliver() to send the message to just one client. | PriceActionAppender creates a TradeEventDispatcher | TransitionDispatcher created by TransitionAppender |
Bayeux channel | /liveUpdate | /service/privateEvent | /historicalUpdate | /transition |
javascript subscription | stripchartframe.html has onload_actions() (called from onload) that calls dojox.cometd.subscribe( "/liveUpdate", onLiveMessage); | JudgeSubFrame.jsp has onload_actions() (called from onload) that calls dojox.cometd.subscribe( "/service/privateEvent",onPrivateMessage); | stripchartframe.html has onload_actions() (called from onload) that calls dojox.cometd.subscribe( "/historicalUpdate",onHistMessage); | stripchartframe.html has onload_actions() (called from onload) that calls dojox.cometd.subscribe( "/transition", onTransitionMessage); |
Server Subscription | NONE | ExperimentServer. ExperimentBayeuxServer constructor calls subscribe( PrivateEventDispatcher. PRIVATE_EVENT_TOPIC_SUFFIX, "sendPrivateUpdate") | Session.initializeMarket() calls tradeHistory = (MockBayeuxChannel) sessionHistory.getChannel( TradeEventDispatcher. TRADE_EVENT_TOPIC_SUFFIX, true); | NONE |
Server Client | NONE | redirect to specific client | private MockBayeuxChannel tradeHistory; | NONE |
PREDICTION MARKETS | MM Price Update (PM) | New Charts (PM) | Transition Events (PM) |
---|---|---|---|
Purpose | Market Maker price update: update prices in table | new price chart is ready: refresh | A new Market opened, give Users a link |
Event | PriceChange created in recordTrade in BinaryMarketMaker or MultiMarketMaker after trade | created in ChartGenerator updateChartFile() and writeMultiStepChartFile() | Transition is created in MarketOwner.newBinaryMarket() or MarketOwner.newMultiMarket() |
Appender | PriceChangeAppender created in AllMarkets.MarketBayeuxService (bayeux, marketName). | NewChartAppender created in AllMarkets.MarketBayeuxService (bayeux, marketName). | TransitionAppender created in MarketBayeuxService constructor(). |
Logger | PriceChange.class | NewChart.class | Transition.class |
callAppenders() | in PriceChange constructor, calls Logger(PriceChange.class) .callAppenders(this) | NewChart constructor | Transition constructors |
Dispatcher | PriceChangeDispatcher created in PriceChangeAppender constructor | NewChartDispatcher created by NewChartAppender | TransitionDispatcher created by TransitionAppender |
Filtering | PriceChangeDispatcher.publishTransition() | NewChartDispatcher.publishTransition() | NA |
Bayeux channel | Dispatcher.buildChannelName() produces /priceChange/ + marketName | Dispatcher.buildChannelName() produces /newChart/ + marketName | /transition |
javascript subscription | channels.push( dojox.cometd.subscribe( priceUpdateChannel, onPriceUpdate)); | purchaseCost.jsp has onload_actions() (called from onload) that calls dojox.cometd.subscribe( /newChart/+claimName, onPriceUpdate); | purchaseClaim.jsp and purchaseCost.jsp have onload_actions() (called from onload) that call dojox.cometd.subscribe( "/transition", onTransitionMessage); |
© Copyright 2007-2009 Chris Hibbert. All rights reserved. © 2006 CommerceNet Consortium, LLC.
This software is published under the terms of the MIT license, a copy |
|
|||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |