Commit 339db3e2 authored by Bas Lijnse's avatar Bas Lijnse

Removed need for polling and time-based shares

git-svn-id: https://svn.cs.ru.nl/repos/iTask-system/trunk@3010 63da3aa8-80fd-4f01-9db8-e6ea747a3da2
parent 9d1e5646
......@@ -53,7 +53,7 @@ where
| stable
# status = fromJust (fromJSON encv)
# (rep,iworld) = makeRep taskId repOpts status iworld
# iworld = queueWork (Evaluate taskInstance,Nothing) iworld
# iworld = queueRefresh [taskInstance] iworld
= (ValueResult (Value status True) {TaskInfo|lastEvent=lastEvent,involvedUsers=[],refreshSensitive=True} rep state, iworld)
| otherwise
//Check status
......@@ -66,7 +66,7 @@ where
Just c = (CompletedProcess c,True, TCBasic taskId lastEvent (toJSON (CompletedProcess c)) False)
Nothing = (RunningProcess cmd,False, state)
# (rep,iworld) = makeRep taskId repOpts status {IWorld|iworld & world = world}
# iworld = queueWork (Evaluate taskInstance,Nothing) iworld
# iworld = queueRefresh [taskInstance] iworld
= (ValueResult (Value status stable) {TaskInfo|lastEvent=lastEvent,involvedUsers=[],refreshSensitive=True} rep state, iworld)
eval event repAs (TCDestroy _) iworld
......
implementation module iTasks.API.Core.SDSCombinators
import StdTuple
import StdTuple, StdClass
import iTasks.Framework.SDS
import iTasks.API.Core.SDSs
from StdFunc import const, o
......
......@@ -24,47 +24,25 @@ constShare :: !a -> ROShared p a
constShare v = createReadOnlySDS (\_ env -> (v, env))
null :: WriteOnlyShared a
null = createSDS Nothing (\Void env -> (Ok (Void, OnWrite), env)) (\Void _ env -> (Ok (const False), env))
null = createReadWriteSDS SYSTEM_DATA_NS "null" (\Void env -> (Ok Void, env)) (\Void _ env -> (Ok (const False), env))
currentDateTime :: ReadOnlyShared DateTime
currentDateTime = createReadOnlySDSPredictable SYSTEM_DATA_NS "currentDateTime" read
where
read Void iworld=:{current={localDateTime,timestamp=Timestamp ts}}
= ((localDateTime, Timestamp (ts + 1)), iworld)
currentDateTime = mapRead (\(d,t) -> DateTime d t) (iworldLocalDate |+| iworldLocalTime)
currentTime :: ReadOnlyShared Time
currentTime = createReadOnlySDSPredictable SYSTEM_DATA_NS "currentTime" read
where
read Void iworld=:{current={localDateTime=DateTime _ time,timestamp=Timestamp ts}}
= ((time, Timestamp (ts + 1)), iworld)
currentTime = toReadOnly iworldLocalTime
currentDate :: ReadOnlyShared Date
currentDate = createReadOnlySDSPredictable SYSTEM_DATA_NS "currentDate" read
where
read Void iworld=:{current={localDateTime=DateTime date time,timestamp=Timestamp ts}}
= ((date, Timestamp (ts + secondsUntilChange time)), iworld)
secondsUntilChange {Time|hour,min,sec} = (23-hour)*3600 + (59-min)*60 + (60-sec)
currentDate = toReadOnly iworldLocalDate
currentUTCDateTime :: ReadOnlyShared DateTime
currentUTCDateTime = createReadOnlySDSPredictable SYSTEM_DATA_NS "currentUTCDateTime" read
where
read Void iworld=:{current={utcDateTime,timestamp=Timestamp ts}}
= ((utcDateTime, Timestamp (ts + 1)), iworld)
currentUTCDateTime = mapRead (\(d,t) -> DateTime d t) (iworldUTCDate |+| iworldUTCTime)
currentUTCTime :: ReadOnlyShared Time
currentUTCTime = createReadOnlySDSPredictable SYSTEM_DATA_NS "currentUTCTime" read
where
read Void iworld=:{current={utcDateTime=DateTime _ time,timestamp=Timestamp ts}}
= ((time, Timestamp (ts + 1)), iworld)
currentUTCTime = toReadOnly iworldUTCTime
currentUTCDate :: ReadOnlyShared Date
currentUTCDate = createReadOnlySDSPredictable SYSTEM_DATA_NS "currentUTCDate" read
where
read Void iworld=:{current={utcDateTime=DateTime date time,timestamp=Timestamp ts}}
= ((date, Timestamp (ts + secondsUntilChange time)), iworld)
secondsUntilChange {Time|hour,min,sec} = (23-hour)*3600 + (59-min)*60 + (60-sec)
currentUTCDate = toReadOnly iworldUTCDate
// Workflow processes
topLevelTasks :: SharedTaskList Void
......@@ -130,17 +108,10 @@ where
randomInt Void iworld=:{IWorld|random=[i:is]}
= (i, {IWorld|iworld & random = is})
EXTERNAL_FILE_POLLING_RATE :== 10
externalFile :: !FilePath -> Shared String
externalFile path = createPollingSDS "externalFile" path read write
externalFile path = createReadWriteSDS "externalFile" path read write
where
read Void iworld
# (Timestamp ts, iworld) = 'iFU'.currentTimestamp iworld
# (res, iworld) = read` iworld
= (fmap (\r -> (r, Timestamp (ts + EXTERNAL_FILE_POLLING_RATE), checkF r)) res, iworld)
read` iworld=:{world}
read Void iworld=:{world}
# (ok,file,world) = fopen path FReadData iworld.world
| not ok = (Ok "", {IWorld|iworld & world = world}) // empty string if file doesn't exist
# (res,file) = readAll file
......@@ -148,13 +119,7 @@ where
| not ok = (Error (toString CannotClose) ,{IWorld|iworld & world = world})
| isError res = (Error (toString (fromError res)) ,{IWorld|iworld & world = world})
= (Ok (fromOk res), {IWorld|iworld & world = world})
checkF old iworld
# (res,iworld)= read` iworld
| isOk res && (fromOk res) <> old = (Changed, iworld)
# (Timestamp ts, iworld) = 'iFU'.currentTimestamp iworld
= (CheckAgain (Timestamp (ts + EXTERNAL_FILE_POLLING_RATE)), iworld)
write Void content iworld=:{world}
# (ok,file,world) = fopen path FWriteText world
| not ok = (Error (toString CannotOpen), {IWorld|iworld & world = world})
......
......@@ -378,9 +378,9 @@ where
//SHARED HELPER FUNCTIONS
addTaskToList :: !TaskId !(!ParallelTaskType,!ParallelTask a) !(Maybe Int) !*IWorld -> (!TaskListEntry,!*IWorld) | iTask a
addTaskToList taskId (parType,parTask) mbPos iworld=:{current={taskTime,user,attachmentChain,localDateTime}}
addTaskToList taskId (parType,parTask) mbPos iworld=:{current={taskTime,user,attachmentChain},clocks={localDate,localTime}}
# (list,iworld) = loadTaskList taskId iworld
# progress = {value=None, issuedAt=localDateTime,issuedBy=user,involvedUsers=[],firstEvent=Nothing,latestEvent=Nothing}
# progress = {value=None, issuedAt=DateTime localDate localTime,issuedBy=user,involvedUsers=[],firstEvent=Nothing,latestEvent=Nothing}
# (taskIda,name,state,iworld) = case parType of
Embedded
# (taskIda,iworld=:{current=current=:{localTasks}}) = getNextTaskId iworld
......@@ -547,7 +547,7 @@ where
Ok meta
//Just steal the instance, TODO, make stealing optional
# (_,iworld) = write {TIMeta|meta & instanceType=AttachedInstance [taskId:attachmentChain] user} (taskInstanceMeta instanceNo) iworld
# iworld = queueUrgentEvaluate instanceNo iworld
# iworld = queueUrgentRefresh [instanceNo] iworld
= eval event repOpts (TCBasic taskId ts JSONNull False) iworld
Error e
= (ExceptionResult (dynamic e) e,iworld)
......
......@@ -194,11 +194,11 @@ where
= case mbl of
Ok l
# iworld = {iworld & ioValues = 'Data.Map'.put taskId (IOValue (dynamic l) False) ioValues}
# iworld = addOutdatedInstances [(instanceNo,Nothing)] iworld
# iworld = queueRefresh [instanceNo] iworld
= (sends,close,dynamic (r,l), iworld)
Error e
# iworld = {iworld & ioValues = 'Data.Map'.put taskId (IOException e) ioValues}
# iworld = addOutdatedInstances [(instanceNo,Nothing)] iworld
# iworld = queueRefresh [instanceNo] iworld
= (sends,True,dynamic e, iworld)
Error e
= ([],True,dynamic (toString e), iworld)
......@@ -212,11 +212,11 @@ where
= case mbl of
Ok l
# iworld = {iworld & ioValues = 'Data.Map'.put taskId (IOValue (dynamic l) True) ioValues}
# iworld = addOutdatedInstances [(instanceNo,Nothing)] iworld
# iworld = queueRefresh [instanceNo] iworld
= (dynamic (r,l), iworld)
Error e
# iworld = {iworld & ioValues = 'Data.Map'.put taskId (IOException e) ioValues}
# iworld = addOutdatedInstances [(instanceNo,Nothing)] iworld
# iworld = queueRefresh [instanceNo] iworld
= (dynamic e, iworld)
Error e
= (dynamic (toString e), iworld)
......
......@@ -12,7 +12,7 @@ derive class iTask SQLValue, SQLDate, SQLTime
sqlShare :: String (A.*cur: *cur -> *(MaybeErrorString r,*cur) | SQLCursor cur)
(A.*cur: w *cur -> *(MaybeErrorString Void, *cur) | SQLCursor cur) -> RWShared SQLDatabase r w
sqlShare name readFun writeFun = createChangeOnWriteSDS "SQLShares" name read write
sqlShare name readFun writeFun = createReadWriteSDS "SQLShares" name read write
where
read db iworld
# (mbOpen,iworld) = openMySQLDb db iworld
......@@ -74,7 +74,7 @@ sqlExecuteSelect :: SQLDatabase SQLStatement ![SQLValue] -> Task [SQLRow]
sqlExecuteSelect db query values = sqlExecute db [] (execSelect query values)
sqlSelectShare :: String SQLStatement ![SQLValue] -> ROShared SQLDatabase [SQLRow]
sqlSelectShare name query values = createChangeOnWriteSDS "SQLShares" name read write
sqlSelectShare name query values = createReadWriteSDS "SQLShares" name read write
where
read db iworld
# (mbOpen,iworld) = openMySQLDb db iworld
......
......@@ -116,10 +116,14 @@ createClientIWorld serverURL currentInstance
,publicWebDirectories = locundef "publicWebDirectories" }
,customCSS = False }
,config = {sessionTime = 3600, smtpServer = locundef "smtpServer"}
,clocks =
{ localDate = {Date|day = 1, mon = 1, year = 1977}
, localTime = {Time|hour = 0, min = 0, sec = 0}
, utcDate = {Date|day = 1, mon = 1, year = 1977}
, utcTime = {Time|hour = 0, min = 0, sec = 0}
}
,current =
{timestamp = Timestamp 1
,utcDateTime = DateTime {Date|day = 1, mon = 1, year = 1977} {Time|hour = 0, min = 0, sec = 0}
,localDateTime = DateTime {Date|day = 1, mon = 1, year = 1977} {Time|hour = 0, min = 0, sec = 0}
,taskTime = 0
,taskInstance = currentInstance
,sessionInstance = Just currentInstance
......@@ -139,7 +143,7 @@ createClientIWorld serverURL currentInstance
,jsCompilerState = locundef "jsCompilerState"
,ti = 'Data.Map'.newMap
,nextInstanceNo = 0
,workQueue = []
,refreshQueue = []
,uiUpdates = 'Data.Map'.newMap
,shutdown = False
,random = genRandInt seed
......
......@@ -53,9 +53,6 @@ RELATIVE_LOCATIONS :== [".": take 5 (iterate ((</>) "..") "..")]
*/
startEngine :: a !*World -> *World | Publishable a
// Background process. TODO
background :: !*IWorld -> *IWorld
/**
* Wraps a task together with a url to make it publishable by the engine
*/
......@@ -70,3 +67,6 @@ instance Publishable (HTTPRequest -> Task a) | iTask a
instance Publishable [PublishedTask]
determineAppName :: !*World -> (!String,!*World)
// Background process. TODO
background :: !*IWorld -> *IWorld
implementation module iTasks.Framework.Engine
import StdMisc, StdArray, StdList, StdOrdList, StdTuple, StdChar, StdFile, StdBool
import StdMisc, StdArray, StdList, StdOrdList, StdTuple, StdChar, StdFile, StdBool, StdEnum
from StdFunc import o, seqList, ::St
import Data.Map, Data.Error, Data.Func, Data.Tuple, Math.Random, Internet.HTTP, Text, Text.Encodings.MIME, Text.Encodings.UrlEncoding
import System.Time, System.CommandLine, System.Environment, System.OSError, System.File, System.FilePath, System.Directory
......@@ -47,7 +47,7 @@ startEngine publishable world
# iworld = initShareRegistrations iworld
// mark all instance as outdated initially
# (maxNo,iworld) = maxInstanceNo iworld
# iworld = addOutdatedInstances [(instanceNo, Nothing) \\ instanceNo <- [1..maxNo]] iworld
# iworld = queueRefresh [1..maxNo] iworld
# iworld = serve port (httpServer port keepalive (engine publishable)) (BackgroundTask background) timeout iworld
= finalizeIWorld iworld
where
......@@ -119,29 +119,10 @@ MAX_TIMEOUT :== 86400000 // one day
background :: !*IWorld -> *IWorld
background iworld
# iworld = updateCurrentDateTime iworld
# (mbWork, iworld) = dequeueWork iworld
# iworld = case mbWork of
Empty
= iworld
Work work
# iworld = case work of
(Evaluate instanceNo) = refreshTaskInstance instanceNo iworld
(EvaluateUrgent instanceNo) = refreshTaskInstance instanceNo iworld
(TriggerSDSChange sdsId) = addOutdatedOnShareChange sdsId (const True) iworld
(CheckSDS sdsId hash checkF)
# (checkRes,iworld) = checkF iworld
= case checkRes of
Changed = addOutdatedOnShareChange sdsId (const True) iworld
(CheckAgain time) = queueWork (CheckSDS sdsId hash checkF, Just time) iworld
= iworld // give http server the chance to handle request
WorkAt time
= iworld
/*
# (curTime, iworld) = currentTimestamp iworld
= (Just (toTimeout curTime time), iworld)
*/
= iworld
# iworld = updateClocks iworld
= case dequeueRefresh iworld of
(Just instanceNo,iworld) = refreshTaskInstance instanceNo iworld
(_,iworld) = iworld
// The iTasks engine consist of a set of HTTP request handlers
engine :: publish -> [(!String -> Bool
......@@ -172,8 +153,8 @@ initIWorld sdkDir world
# tm = (fromOk res).lastModifiedTime
# build = strfTime "%Y%m%d-%H%M%S" tm
# (timestamp,world) = time world
# (localDateTime,world) = currentLocalDateTimeWorld world
# (utcDateTime,world) = currentUTCDateTimeWorld world
# (DateTime localDate localTime,world) = currentLocalDateTimeWorld world
# (DateTime utcDate utcTime,world) = currentUTCDateTimeWorld world
# (_,world) = ensureDir "data" dataDir world
# tmpDir = dataDir </> "tmp-" +++ build
# (_,world) = ensureDir "tmp" tmpDir world
......@@ -207,11 +188,16 @@ initIWorld sdkDir world
,customCSS = customCSS
}
,config = initialConfig
,clocks =
{SystemClocks
|localDate=localDate
,localTime=localTime
,utcDate=utcDate
,utcTime=utcTime
}
,current =
{TaskEvalState
|timestamp = timestamp
,utcDateTime = utcDateTime
,localDateTime = localDateTime
,taskTime = 0
,taskInstance = 0
,sessionInstance = Nothing
......@@ -230,7 +216,7 @@ initIWorld sdkDir world
,jsCompilerState = (lst, ftmap, flavour, Nothing, newMap)
,ti = newMap
,nextInstanceNo = 0
,workQueue = []
,refreshQueue = []
,uiUpdates = newMap
,shutdown = False
,io = {done = [], todo = []}
......
......@@ -8,7 +8,7 @@ from Data.Set import :: Set
from StdFile import class FileSystem
from System.Time import :: Timestamp
from Text.JSON import :: JSONNode
from iTasks.API.Core.Types import :: DateTime, :: User, :: Config, :: InstanceNo, :: TaskNo, :: TaskId, :: TaskListItem, :: ParallelTaskType, :: TaskTime, :: SessionId
from iTasks.API.Core.Types import :: Date, :: Time, :: DateTime, :: User, :: Config, :: InstanceNo, :: TaskNo, :: TaskId, :: TaskListItem, :: ParallelTaskType, :: TaskTime, :: SessionId
from iTasks.Framework.UIDefinition import :: UIDef, :: UIControl, :: UIEditletOpts
from iTasks.Framework.UIDiff import :: UIUpdate, :: UIEditletDiffs
from iTasks.Framework.TaskState import :: TaskListEntry, :: TIMeta
......@@ -24,6 +24,7 @@ from TCPIP import :: TCP_Listener, :: TCP_Listener_, :: TCP_RChannel_, :: TCP_SC
:: *IWorld = { server :: !ServerInfo // Static server info, initialized at startup
, config :: !Config // Server configuration
, clocks :: !SystemClocks // Server side clocks
, current :: !TaskEvalState // Shared state during task evaluation
, random :: [Int] // Infinite random stream
......@@ -41,7 +42,7 @@ from TCPIP import :: TCP_Listener, :: TCP_Listener_, :: TCP_RChannel_, :: TCP_SC
, ti :: !Map InstanceNo TIMeta // Task instance index
, nextInstanceNo :: !Int // Next task instance number
, workQueue :: ![(!Work,!Maybe Timestamp)] // (Instance input)
, refreshQueue :: ![InstanceNo] // Instances that need refreshing
, uiUpdates :: !Map InstanceNo [UIUpdate] // (Instance output)
, io :: !*IOTasks // The low-level input/output tasks
......@@ -70,10 +71,15 @@ from TCPIP import :: TCP_Listener, :: TCP_Listener_, :: TCP_RChannel_, :: TCP_SC
, publicWebDirectories :: ![FilePath] // List of directories that contain files that are served publicly by the iTask webserver
}
:: SystemClocks =
{ localDate :: !Date
, localTime :: !Time
, utcDate :: !Date
, utcTime :: !Time
}
:: TaskEvalState =
{ timestamp :: !Timestamp // The timestamp of the current request
, utcDateTime :: !DateTime // The local date & time of the current request
, localDateTime :: !DateTime // The local date & time of the current request
, taskTime :: !TaskTime // The 'virtual' time for the task. Increments at every event
, taskInstance :: !InstanceNo // The current evaluated task instance
, sessionInstance :: !Maybe InstanceNo // If we are evaluating a task in response to an event from a session
......@@ -104,12 +110,14 @@ from TCPIP import :: TCP_Listener, :: TCP_Listener_, :: TCP_RChannel_, :: TCP_SC
:: *Resource = Resource | .. //Extensible resource type for caching database connections etc...
:: Work = Evaluate !InstanceNo
| EvaluateUrgent !InstanceNo
| TriggerSDSChange !BasicShareId
| CheckSDS !BasicShareId !Hash (*IWorld -> *(!CheckRes, !*IWorld))
//Internally used clock shares
iworldLocalDate :: Shared Date
iworldLocalTime :: Shared Time
iworldUTCDate :: Shared Date
iworldUTCTime :: Shared Time
updateCurrentDateTime :: !*IWorld -> *IWorld
//Update the clock shares
updateClocks :: !*IWorld -> *IWorld
getResponseExpiry :: !InstanceNo !*IWorld -> (!Maybe Int, !*IWorld)
......@@ -118,7 +126,3 @@ popUIUpdates :: ![InstanceNo] !*IWorld -> (![(!InstanceNo,![UIUpda
clearUIUpdates :: !InstanceNo !*IWorld -> *IWorld
instance FileSystem IWorld
//Sync work queue to disk (Only used with CGI wrapper)
saveWorkQueue :: !*IWorld -> *IWorld
restoreWorkQueue :: !*IWorld -> *IWorld
......@@ -11,20 +11,53 @@ from iTasks.Framework.UIDiff import :: UIUpdate
from StdFile import class FileSystem(..)
from StdFile import instance FileSystem World
from StdFunc import const
from Data.List import splitWith
from TCPIP import :: TCP_Listener, :: TCP_Listener_, :: TCP_RChannel_, :: TCP_SChannel_, :: TCP_DuplexChannel, :: DuplexChannel, :: IPAddress, :: ByteSeq
import System.Time, StdList, Text.Encodings.Base64, _SystemArray, StdBool, StdTuple, Text.JSON, Data.Error, Data.Map
import iTasks.Framework.TaskStore, iTasks.Framework.Util
import iTasks.Framework.SerializationGraphCopy
import iTasks.Framework.SerializationGraphCopy
import iTasks.Framework.SDS
updateCurrentDateTime :: !*IWorld -> *IWorld
updateCurrentDateTime iworld=:{IWorld|current,world}
# (timestamp,world) = time world
# (localDt,world) = currentLocalDateTimeWorld world
# (utcDt,world) = currentUTCDateTimeWorld world
= {IWorld|iworld & current = {current & timestamp = timestamp, utcDateTime = utcDt, localDateTime = localDt}, world = world}
iworldLocalDate :: Shared Date
iworldLocalDate = createReadWriteSDS "IWorld" "localDate" read write
where
read Void iworld=:{IWorld|clocks={localDate}} = (Ok localDate,iworld)
write Void localDate iworld=:{IWorld|clocks} = (Ok (const True), {iworld & clocks = {clocks & localDate=localDate}})
iworldLocalTime :: Shared Time
iworldLocalTime = createReadWriteSDS "IWorld" "localTime" read write
where
read Void iworld=:{IWorld|clocks={localTime}} = (Ok localTime,iworld)
write Void localTime iworld=:{IWorld|clocks} = (Ok (const True), {iworld & clocks = {clocks & localTime=localTime}})
iworldUTCDate :: Shared Date
iworldUTCDate = createReadWriteSDS "IWorld" "utcDate" read write
where
read Void iworld=:{IWorld|clocks={utcDate}} = (Ok utcDate,iworld)
write Void utcDate iworld=:{IWorld|clocks} = (Ok (const True), {iworld & clocks = {clocks & utcDate=utcDate}})
iworldUTCTime :: Shared Time
iworldUTCTime = createReadWriteSDS "IWorld" "utcTime" read write
where
read Void iworld=:{IWorld|clocks={utcTime}} = (Ok utcTime,iworld)
write Void utcTime iworld=:{IWorld|clocks} = (Ok (const True), {iworld & clocks = {clocks & utcTime=utcTime}})
updateClocks :: !*IWorld -> *IWorld
updateClocks iworld=:{IWorld|clocks,current,world}
# (timestamp,world) = time world
//Determine current date and time
# (DateTime localDate localTime,world) = currentLocalDateTimeWorld world
# (DateTime utcDate utcTime,world) = currentUTCDateTimeWorld world
# iworld = {IWorld|iworld & current = {current & timestamp = timestamp}, world = world}
//Write SDS's if necessary
# iworld = if (localDate == clocks.localDate) iworld (snd (write localDate iworldLocalDate iworld))
# iworld = if (localTime == clocks.localTime) iworld (snd (write localTime iworldLocalTime iworld))
# iworld = if (utcDate == clocks.utcDate) iworld (snd (write utcDate iworldUTCDate iworld))
# iworld = if (utcTime == clocks.utcTime) iworld (snd (write utcTime iworldUTCTime iworld))
= iworld
//Determine the expiration of request, thereby determining the poll interval of
//polling clients
......@@ -33,17 +66,8 @@ FAST_EXPIRY :== 100
IMMEDIATE_EXPIRY :== 0
getResponseExpiry :: !InstanceNo !*IWorld -> (!Maybe Int, !*IWorld)
getResponseExpiry instanceNo iworld=:{workQueue}
= (Just (expiry instanceNo workQueue), iworld)
where
expiry _ [] = REGULAR_EXPIRY
expiry instanceNo [(Evaluate _,Just (Timestamp 0)):ws] //HACK...
= IMMEDIATE_EXPIRY
expiry instanceNo [(Evaluate evalNo,_):ws]
| evalNo == instanceNo = FAST_EXPIRY
= expiry instanceNo ws
expiry instanceNo [_:ws] = expiry instanceNo ws
getResponseExpiry instanceNo iworld=:{refreshQueue=[]} = (Just REGULAR_EXPIRY,iworld)
getResponseExpiry instanceNo iworld=:{refreshQueue} = (Just FAST_EXPIRY,iworld)
addUIUpdates :: !InstanceNo ![UIUpdate] !*IWorld -> *IWorld
addUIUpdates instanceNo [] iworld = iworld
......@@ -76,17 +100,3 @@ where
sfopen filename mode iworld=:{IWorld|world}
# (ok,file,world) = sfopen filename mode world
= (ok,file,{IWorld|iworld & world = world})
// serialise Work as dynamic since it contains functions on unique states
JSONEncode{|Work|} work = [JSONArray [JSONString "_FUNCTION_", JSONString (base64URLEncode (serialize work))]]
JSONDecode{|Work|} [JSONArray [JSONString "_FUNCTION_",JSONString string]:c] = (Just (fromOk(deserialize {s` \\ s` <-: base64URLDecode string})) ,c)
WORKQUEUE_INDEX :== "workqueue-index"
saveWorkQueue :: !*IWorld -> *IWorld
saveWorkQueue iworld=:{workQueue} = storeValue NS_TASK_INSTANCES WORKQUEUE_INDEX workQueue iworld
restoreWorkQueue :: !*IWorld -> *IWorld
restoreWorkQueue iworld
# (mbWorkQueue,iworld) = loadValue NS_TASK_INSTANCES WORKQUEUE_INDEX iworld
= {iworld & workQueue = fromMaybe [] mbWorkQueue}
definition module iTasks.Framework.SDS
import StdClass
import System.FilePath, Data.Void, Data.Maybe, Data.Either, Data.Error, System.Time, Text.JSON
from iTasks.Framework.IWorld import :: IWorld
from iTasks.API.Core.Types import :: InstanceNo
......@@ -19,7 +20,7 @@ from iTasks.API.Core.Types import :: InstanceNo
:: SDSSource p r w =
{ mbId :: !Maybe BasicShareId
, read :: p *IWorld -> *(!MaybeErrorString (!r,!ChangeNotification), !*IWorld)
, read :: p *IWorld -> *(!MaybeErrorString r, !*IWorld)
, write :: p w *IWorld -> *(!MaybeErrorString (SDSNotifyPred p), !*IWorld)
}
......@@ -30,10 +31,9 @@ from iTasks.API.Core.Types import :: InstanceNo
//Notification requests are stored in the IWorld
:: SDSNotifyRequest =
{ reqid :: Int
{ taskInstance :: InstanceNo
, sdsid :: SDSIdentity
, param :: Dynamic
, taskInstance :: InstanceNo
}
:: SDSIdentity :== String
......@@ -82,9 +82,9 @@ from iTasks.API.Core.Types import :: InstanceNo
, writer :: SDSWriteProjection r2 w2 w
}
:: ChangeNotification = OnWrite
| Predictable !Timestamp
| Polling !Timestamp !(*IWorld -> *(!CheckRes,!*IWorld))
:: ChangeNotification
= OnWrite
//| Polling !Timestamp !(*IWorld -> *(!CheckRes,!*IWorld))
:: CheckRes = Changed | CheckAgain Timestamp
......@@ -102,11 +102,8 @@ from iTasks.API.Core.Types import :: InstanceNo
registerSDSDependency :: !BasicShareId !InstanceNo !*IWorld -> *IWorld
reportSDSChange :: !BasicShareId !(InstanceNo -> Bool) !*IWorld -> *IWorld
registerSDSPredictableChange :: !Timestamp !BasicShareId !*IWorld -> *IWorld
registerSDSCheckForChange :: !Timestamp !Hash !(*IWorld -> (!CheckRes,!*IWorld)) !BasicShareId !*IWorld -> *IWorld
createChangeOnWriteSDS ::
createReadWriteSDS ::
!String
!String
!(p *IWorld -> *(!MaybeErrorString r, !*IWorld))
......@@ -114,44 +111,15 @@ createChangeOnWriteSDS ::
->
RWShared p r w
createPollingSDS ::
!String
!String
!(p *IWorld -> *(!MaybeErrorString (!r, !Timestamp, !(*IWorld -> *(!CheckRes,!*IWorld))), !*IWorld))
!(p w *IWorld -> *(!MaybeErrorString (SDSNotifyPred p), !*IWorld))
->
RWShared p r w
createReadOnlySDS ::
!(p *IWorld -> *(!r, !*IWorld))
->
ROShared p r
createReadOnlySDSError ::
!(p *IWorld -> *(!MaybeErrorString r, !*IWorld))
->
ROShared p r
createReadOnlySDSPredictable ::
!String
!String
!(p *IWorld -> *(!(!r, !Timestamp), !*IWorld))
->
ROShared p r
createReadOnlySDSErrorPredictable ::
!String
!String
!(p *IWorld -> *(!MaybeErrorString (!r,