on master help sign in
prettify notification printing in tutd
commit722fd2492d68fe27f27c69487c9f703262852eab authorAgentM <agentm@themactionfaction.com> dateMon 1 Feb 2016, 00:50 (11 years ago) parentaa37ec1
3 files changed+72−1
ProjectM36/Client.hs+1 TutorialD/Interpreter.hs+6−1 docs/using_notifications.markdown+65
ProjectM36/Client.hs+1
@@ -43,6 +43,7 @@ module ProjectM36.Client
4343 SessionId,
4444 NotificationCallback,
4545 emptyNotificationCallback,
46+ EvaluatedNotification(..),
4647 AtomType(..)) where
4748import ProjectM36.Base hiding (inclusionDependencies) --defined in this module as well
4849import qualified ProjectM36.Base as B
TutorialD/Interpreter.hs+6−1
@@ -119,7 +119,12 @@ data InterpreterConfig = LocalInterpreterConfig PersistenceStrategy HeadName|
119119 RemoteInterpreterConfig C.NodeId C.DatabaseName HeadName
120120
121121outputNotificationCallback :: C.NotificationCallback
122−outputNotificationCallback notName evaldNot = hPutStrLn stderr $ "Notification received \"" ++ show notName ++ "\": " ++ show evaldNot
122+outputNotificationCallback notName evaldNot = hPutStrLn stderr $ "Notification received " ++ show notName ++ ":\n" ++ show (reportExpr (C.notification evaldNot)) ++ "\n" ++ prettyEvaluatedNotification evaldNot
123+
124+prettyEvaluatedNotification :: C.EvaluatedNotification -> String
125+prettyEvaluatedNotification eNotif = case C.reportRelation eNotif of
126+ Left err -> show err
127+ Right reportRel -> T.unpack (showRelation reportRel)
123128
124129reprLoop :: InterpreterConfig -> C.SessionId -> C.Connection -> IO ()
125130reprLoop config sessionId conn = do
docs/using_notifications.markdownnew file+65
@@ -0,0 +1,65 @@
1+# Using Notifications in Project:M36
2+
3+Interactive 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.
4+
5+As 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.
6+
7+## What is a Notification?
8+
9+A Project:M36 notification is comprised of three user-selected parts:
10+
11+1. an arbitrary notification name: used to uniquely identify the notification in the server and client
12+2. a trigger relational expression: when the outcome of this relational expression changes between two transactions, the notification is fired
13+3. a report relational expression: when the notification fires, the expression is evaluated and passed along
14+
15+By separating the "trigger" and "report" expressions, database users control what kind of reporting they receive when the outcome of a relational expression changes.
16+
17+Currently, notifications are sent to all connected clients and not only to the client which created the notification. This may change in the future.
18+
19+## Creating a Notification
20+
21+Notifications can be created in the ```tutd``` TutorialD interpreter with the following syntax:
22+
23+```
24+notify <notification name> <trigger relational expression> <report relational expression>
25+```
26+
27+## Deleting a Notification
28+
29+Notifications are uniquely identified by name and are shared among all clients. To delete a notification for all clients:
30+
31+```
32+unnotify <notification name>
33+```
34+
35+## A Motivating Example
36+
37+Consider the following ```person``` relation variable where "name" is a key:
38+
39+```
40+TutorialD (master): person:=relation{tuple{name "Steve",address "Main St."},tuple{name "John", address "Elm St."}}
41+TutorialD (master): :showexpr person
42+┌────────┬─────┐
43+│address │name │
44+├────────┼─────┤
45+│Elm St. │John │
46+│Main St.│Steve│
47+└────────┴─────┘
48+```
49+
50+If a remote application is currently the address in the tuple for "Steve", then it would install a notification for that tuple's key:
51+
52+```
53+TutorialD (master): notify steve_change person where name="Steve" (person where name="Steve"){address}
54+TutorialD (master): :commit
55+```
56+
57+Then, when any client including the initiating client updates the "Steve" tuple, an asynchronous notification is fired:
58+
59+```
60+TutorialD (master): update person where name="Steve" (address:="Grove St.")
61+TutorialD (master): :commit
62+TutorialD (master): Notification received "steve_change": ...
63+```
64+
65+The notification contains the result from the evaluated report relational expression.