reference to undefined name 'graphviz' Exception of type 'MindTouch.Deki.Script.Runtime.DekiScriptUndefinedNameException' was thrown. (click for details)Callstack:
at User:dev/Specs_(Implemented)/Notifications
MindTouch.Deki.Script.Runtime.DekiScriptUndefinedNameException: reference to undefined name 'graphviz' Exception of type 'MindTouch.Deki.Script.Runtime.DekiScriptUndefinedNameException' was thrown.
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptVar expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Expr.DekiScriptVar.VisitWith[DekiScriptExpressionEvaluationState,Range] (IDekiScriptExpressionVisitor`2 visitor, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Evaluate (MindTouch.Deki.Script.Expr.DekiScriptAccess expr, DekiScriptExpressionEvaluationState state, Boolean evaluateProperties) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptAccess expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Expr.DekiScriptAccess.VisitWith[DekiScriptExpressionEvaluationState,Range] (IDekiScriptExpressionVisitor`2 visitor, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptCall expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Expr.DekiScriptCall.VisitWith[DekiScriptExpressionEvaluationState,Range] (IDekiScriptExpressionVisitor`2 visitor, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptSequence expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Expr.DekiScriptSequence.VisitWith[DekiScriptExpressionEvaluationState,Range] (IDekiScriptExpressionVisitor`2 visitor, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptReturnScope expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
Services
- Broadcast: forward single alert to all subscribing services. Uses either HTTP or XMPP depending on configuration.
- Indexer: cares about page/file alerts. Triggers page/file to re re-indexed.
- WatchlistObserver: check modified page/file alert against user watchlist and notify user if need be
- CommentObserver: check comments for username and turn them into user notifications
- UserNotifier: deliver notification to user
Potentially useful technologies
Use cases
- Get changes for a page or optionally its descendants emailed
- Page change as a result of dekiscript output change?
- Get a periodic digest of changes
- Based on search results??
- Filters
- New pages created
- Comment posts
- File attached
- Page moved
- Page updated
- A descendant of a page
- Notify another user or GROUP of users to look at a page or some URI?
Alerts
- page/file: added, removed, modified, moved, restored, wiped
- Optional flag: include descendants
- user: added, removed, renamed, logged in, logged out
- Are groups relevant here?
- initial login
- comments: added, changed, removed
- permission: changed
- service: added, removed, restarted
- user-message: send
- errors:
- on page render if page was edited more than XXX minutes ago
- on api call failure
XML Notification Envelope
- user who triggered it
- alert type
- affected resource
- alert meta-data
User Interface
- A screen that shows your notification settings and allows setting up new alerts. This would need to be driven by a Deki API that exposes CRUD for these alerts.
API Interface
- POST: users/{userid}/alerts
- PUT: users/{userid}/alerts/{alertid}
- GET: users/{userid}/alerts
- GET: users/{userid}/alerts/{alertid}
DB Model for subscription settings
- Needs to store:
- Who is subscribed
- to what events
- delivered by what mechanism
- with what settings
- how often
Delivery mechanisms
- HTTP post to a URI
- XMPP message to an account/channel
- SMTP message
- Can the email address be configured or is it always the users address? Is lack of email confirmation a concern?
- IRC message
- Local executable
- Twitter/Yammer/etc
- ???
Recent changes/transactions DB tables
- Transaction table can log every alert type (as listed above)
- Recent changes API expanded
- Allow filtering by event(s)
- Allow filtering by date ranges
- Why?
- Will allow users to get an rss feed of their subscriptions
- Will allow simpler digest creation for users (simply query the rc api)
- Provides persistence of alerts allowing observer services to uniquely identify each alert by id and retry delivery failures
- Allows for improvements in the frontend recent changes screen
- Allow natural associations between notifications to system events
- Why not?
Related forum posts
Design q's:
- How to efficiently determine for a given alert who is subscribed if the subscription has options/filters?
- Example: I want to get notified about comment posts for page foo and all of its descendants.
- Throttling of pushing out events to observers and messages to delivery services. Each event/message is being handled on its own thread in a simple event driven push model. These services may get overwhelmed. A queuing/long polling model that simulates pub/sub by giving each subscriber a channel could be worth considering.
Implementation Components
DekiNotificationObserver
Accepts events from Deki and generates messages for delivery to end users
Startup
- Subscribe to all configured channels
Lifecycle
An instance of this service (and other observers) is needed for each DekiInstance and its lifecycle needs to be managed by the starting/stopping of a DekiInstance.
Input
- Triggered by http posts of Deki events from the subscribed channel(s)
Flow
- Determine which users are subscribed to the events by calling Deki API's GET:subscriptions with an eventid or guid
- If there are subscriptions
- Build the message based on the event type by calling Deki API features to retrieve more details of the change
- Message includes a list of receipients with all necessary info for delivery
- Publish message to the delivery bus
- TODO: determining correct channel on the delivery bus. Or is it always one channel name which can be configured
DeliveryServices
Deliver messages with endpoint-specific logic
Startup
- Subscribe to all configured channels
Lifecycle
DeliveryServices are global to Deki meaning that a DeliveryService instance can operate for multiple DekiInstances. Its lifecycle (startup/shutdown) is managed by the DekiService.
Specific DeliveryServices such as the SMTP via HTTP proxy service can be started automatically on Deki startup if no deliveryservice xml block exists in the Deki configuration. In this case, Deki's default MessageBus and a well known delivery channel is given to the DeliveryService for subscription.
Input
- Triggered by http posts of prepared messages.
Flow
- Look at recepients and determine if the message can be delivered by this service type
- Deliver the message by executing transport-specific logic to all the recepients
MessageBus
Described in detail here
CronService
Pushes timing events into channels so that services can subscribe to the hourly, minute, etc. channels to get tickled at a regular interval
Really looking forward to seeing this in action!