TaskStore.dcl 7.24 KB
Newer Older
1
definition module iTasks.Internal.TaskStore
2
/**
Bas Lijnse's avatar
Bas Lijnse committed
3
* This module provides storage of task instances
4 5 6
* It contains two types of task instances:
* Session instances: temporary tasks for each interactive session between a user and the server. 
* Workflow instances: persistent long-running tasks that may be shared between users and exist between sessions.
7
*/
8

9
import iTasks.Internal.Task, iTasks.Internal.TaskState, iTasks.UI.Definition, iTasks.Internal.SDS
10
import iTasks.WF.Combinators.Core
11
import iTasks.Extensions.Document
12
import Data.GenEq
13

14 15
from Data.Maybe     import :: Maybe
from Data.Error     import :: MaybeError
16
from Data.Queue 	import :: Queue
17
from System.Time    import :: Timestamp
18

19
:: InstanceFilter =
20
    { //'Vertical' filters
21
      onlyInstanceNo    :: !Maybe [InstanceNo]
22
    , notInstanceNo     :: !Maybe [InstanceNo]
23
    , onlySession       :: !Maybe Bool
24
	, matchAttribute 	:: !Maybe (!String,!String)
25
      //'Horizontal' filters
26 27 28
    , includeConstants  :: !Bool
    , includeProgress   :: !Bool
    , includeAttributes :: !Bool
29
    }
30

31
:: InstanceData :== (!InstanceNo,!Maybe InstanceConstants,!Maybe InstanceProgress,!Maybe TaskAttributes)
32

33 34 35 36
derive class iTask InstanceFilter

//Fresh identifier generation
newInstanceNo           :: !*IWorld -> (!MaybeError TaskException InstanceNo,!*IWorld)
37
newInstanceKey          :: !*IWorld -> (!InstanceKey,!*IWorld)
Bas Lijnse's avatar
Bas Lijnse committed
38
newDocumentId			:: !*IWorld -> (!DocumentId, !*IWorld)
39

40 41 42
//=== Task instance index: ===

//A global index of all task instances is maintained
43 44 45 46

//This counter is used to ensure unique instance numbers
nextInstanceNo :: RWShared () Int Int

47
//This index contains all meta-data about the task instances on this engine
48 49
taskInstanceIndex :: RWShared () [TIMeta] [TIMeta]

50 51 52 53 54 55 56 57 58 59 60
//Task instance state is accessible as shared data sources
filteredInstanceIndex   :: RWShared InstanceFilter [InstanceData] [InstanceData]

//Filtered views on the instance index
taskInstance            :: RWShared InstanceNo InstanceData InstanceData
taskInstanceConstants   :: ROShared InstanceNo InstanceConstants
taskInstanceProgress    :: RWShared InstanceNo InstanceProgress InstanceProgress
taskInstanceAttributes  :: RWShared InstanceNo TaskAttributes TaskAttributes

topLevelTaskList        :: RWShared TaskListFilter (!TaskId,![TaskListItem a]) [(!TaskId,!TaskAttributes)]

61 62
taskInstanceIO 			:: RWShared InstanceNo (Maybe (!String,!Timestamp)) (Maybe (!String,!Timestamp))
allInstanceIO           :: RWShared () (Map InstanceNo (!String,!Timestamp)) (Map InstanceNo (!String,Timestamp)) 
63

64 65 66
//=== Task instance input: ===

//When events are placed in this queue, the engine will re-evaluate the corresponding task instances.
67 68
taskEvents              :: RWShared () (Queue (InstanceNo,Event)) (Queue (InstanceNo,Event))

69
// === Evaluation state of instances: ===
70 71 72 73
taskInstanceReduct		:: RWShared InstanceNo TIReduct TIReduct
taskInstanceValue       :: RWShared InstanceNo TIValue TIValue
taskInstanceShares      :: RWShared InstanceNo (Map TaskId JSONNode) (Map TaskId JSONNode)

74
//Filtered views on evaluation state of instances:
75

76
//Shared source 
77
localShare              			:: RWShared TaskId a a | iTask a
Jurriën Stutterheim's avatar
Jurriën Stutterheim committed
78

79 80
//Core parallel task list state structure
taskInstanceParallelTaskList        :: RWShared (TaskId,TaskListFilter) [ParallelTaskState] [ParallelTaskState]
81

82 83 84 85 86 87 88 89
//Private interface used during evaluation of parallel combinator
taskInstanceParallelTaskListItem    :: RWShared (TaskId,TaskId,Bool) ParallelTaskState ParallelTaskState

taskInstanceEmbeddedTask            :: RWShared TaskId (Task a) (Task a) | iTask a

//Public interface used by parallel tasks
parallelTaskList                    :: RWShared (!TaskId,!TaskId,!TaskListFilter) (!TaskId,![TaskListItem a]) [(!TaskId,!TaskAttributes)] | iTask a

90 91 92 93 94
//===  Task instance output: ===

//When task instances are evaluated, their output consists of instructions to modify the user interface
//of that instance to reflect the instance's new state

95 96 97 98 99
:: TaskOutputMessage 
	= TOUIChange !UIChange
    | TOException !String
	| TODetach !InstanceNo

Steffen Michels's avatar
Steffen Michels committed
100 101
derive gEq TaskOutputMessage

102 103 104 105
:: TaskOutput :== Queue TaskOutputMessage

taskOutput          :: RWShared () (Map InstanceNo TaskOutput) (Map InstanceNo TaskOutput) 
taskInstanceOutput	:: RWShared InstanceNo TaskOutput TaskOutput
106 107

//=== Access functions: ===
108

109
// Create and delete task instances:
110

111
createClientTaskInstance :: !(Task a) !String !InstanceNo !*IWorld -> *(!MaybeError TaskException TaskId, !*IWorld) |  iTask a
112

113 114
//Create a task instance
createTaskInstance :: !(Task a) !*IWorld -> (!MaybeError TaskException (!InstanceNo,InstanceKey),!*IWorld) | iTask a
115

116 117 118
/**
* Create a stored task instance in the task store (lazily without evaluating it)
* @param The task to store
119 120
* @param Whether it is a top-level task
* @param The task evaluation options
121 122 123 124 125 126 127 128 129
* @param The instance number for the task
* @param Management meta data
* @param The parallel task list to which the task belongs
* @param If the instance needs to be evaluated immediately, the attachment is temporarily set to the issuer
* @param The IWorld state
*
* @return The task id of the stored instance
* @return The IWorld state
*/
130
createDetachedTaskInstance :: !(Task a) !Bool !TaskEvalOpts !InstanceNo !TaskAttributes !TaskId !Bool !*IWorld -> (!MaybeError TaskException TaskId, !*IWorld) | iTask a
131 132 133 134 135 136 137 138 139

/**
* Replace a stored task instance in the task store.
* The execution state is reset, but the meta-data is kept.
* @param The instance id
* @param The new task to store
*
* @param The IWorld state
*/
140
replaceTaskInstance :: !InstanceNo !(Task a) *IWorld -> (!MaybeError TaskException (), !*IWorld) | iTask a
141

142
deleteTaskInstance	:: !InstanceNo !*IWorld -> *(!MaybeError TaskException (), !*IWorld)
143

144 145 146 147 148 149 150 151 152 153 154 155
/**
* Queue an event for a task instance
* events are applied in FIFO order when the task instance is evaluated
*
* By splitting up event queuing and instance evaluation, events can come in asynchronously without
* the need to directly processing them. 
*/
queueEvent :: !InstanceNo !Event !*IWorld -> *IWorld

/** 
* Convenience function for queueing multiple refresh multiple refresh events at once
*/
156
queueRefresh :: ![(!TaskId, !String)] !*IWorld -> *IWorld
157 158 159 160 161 162 163

/**
* Dequeue a task event
*/
dequeueEvent :: !*IWorld -> (!Maybe (InstanceNo,Event),!*IWorld)

/**
164
* Queue ui change task output
165
*/
166
queueUIChange :: !InstanceNo !UIChange !*IWorld -> *IWorld
167 168 169
/**
* Convenience function that queues multiple changes at once
*/
170
queueUIChanges :: !InstanceNo ![UIChange] !*IWorld -> *IWorld
171 172 173 174
/**
* Queue exception change task output
*/
queueException :: !InstanceNo !String !*IWorld -> *IWorld
175

176 177 178 179 180 181 182 183 184 185 186
/**
* When a new viewport is attached to an instance, all events and output are removed
* and a single Reset event is queued
*/
attachViewport :: !InstanceNo !*IWorld -> *IWorld

/**
* When a new viewport is detached from an instance, all events and output are removed
*/
detachViewport :: !InstanceNo !*IWorld -> *IWorld

187 188 189 190
//Documents
createDocument 			:: !String !String !String !*IWorld -> (!MaybeError FileError Document, !*IWorld)
loadDocumentContent		:: !DocumentId !*IWorld -> (!Maybe String, !*IWorld)
loadDocumentMeta		:: !DocumentId !*IWorld -> (!Maybe Document, !*IWorld)
Bas Lijnse's avatar
Bas Lijnse committed
191 192
documentLocation		:: !DocumentId !*IWorld -> (!FilePath,!*IWorld)

193 194 195
//== OBSOLETE ===
//Access to remote shared data
exposedShare 	        :: !String -> 	RWShared p r w	    | iTask r & iTask w & TC r & TC w & TC p & JSONEncode{|*|} p