1# Using Notifications in Project:M36
3Interactive applications should strive to show the most up-to-date data to the user. To that end, Project:M36 supports asynchronously-fired notifications sent from the database server to the client which fire when user-specified relational expressions change between transactions.
5As an example, consider an email application. Users of the applications will want to know right away when new mail arrives, so polling every five minutes can cause a worst-case latency of five minutes for a new email to appear. Using asynchronous notifications in the database, the application is notified immediately upon transaction commit and can update accordingly without delay.
7## What is a Notification?
9A Project:M36 notification is comprised of three user-selected parts:
111. an arbitrary notification name: used to uniquely identify the notification in the server and client
122. a trigger relational expression: when the outcome of this relational expression changes between two transactions, the notification is fired
133. a report relational expression: when the notification fires, the expression is evaluated and passed along
15By separating the "trigger" and "report" expressions, database users control what kind of reporting they receive when the outcome of a relational expression changes.
17Currently, notifications are sent to all connected clients and not only to the client which created the notification. This may change in the future.
19## Creating a Notification
21Notifications can be created in the ```tutd``` TutorialD interpreter with the following syntax:
24notify <notification name> <trigger relational expression> <report relational expression>
27## Deleting a Notification
29Notifications are uniquely identified by name and are shared among all clients. To delete a notification for all clients:
32unnotify <notification name>
35## A Motivating Example
37Consider the following ```person``` relation variable where "name" is a key:
40TutorialD (master/main): person:=relation{tuple{name "Steve",address "Main St."},tuple{name "John", address "Elm St."}}
41TutorialD (master/main): :showexpr person
50If a remote application is currently the address in the tuple for "Steve", then it would install a notification for that tuple's key:
53TutorialD (master/main): notify steve_change person where name="Steve" (person where name="Steve"){address}
54TutorialD (master/main): :commit
57Then, when any client including the initiating client updates the "Steve" tuple, an asynchronous notification is fired:
60TutorialD (master/main): update person where name="Steve" (address:="Grove St.")
61TutorialD (master/main): :commit
62TutorialD (master/main): Notification received "steve_change": ...
65The asynchronously-received notification contains the result from the evaluated report relational expression. The expression, in this case, is the result of the report expression evaluated against the parent transactoin
68TutorialD (master/main): Notification received "steve_change":
69Project (AttributeNames (fromList ["address"])) (Restrict (AttributeEqualityPredicate "name" (NakedAtomExpr Atom "Steve")) (RelationVariable "person"))
77## Notifications with ProjectM36.Client
79First, implement a ```NotificationCallback``` function to perform an IO action when an asynchronous notification is received from the DBMS. Note that this function will not be called on any specific thread; specifically, the callback is *not* triggered by calling into ProjectM36.Client functions.
81Each ProjectM36 Connection can only have one callback and it cannot be changed after Connection creation.
83Then, create a DatabaseExpr using the AddNotification constructor:
86AddNotification <notification name::Text> <change expression::RelationalExpr> <report expression::RelationalExpr>
89and execute it using ```executeDatabaseContextExpr```. In order for a notification to take effect, it must be committed as well.
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list