Commit ed5f11d5 authored by Bas Lijnse's avatar Bas Lijnse

A lot of overdue refactoring and cleanup: ProcessDB task API, some internal...

A lot of overdue refactoring and cleanup: ProcessDB task API, some internal data structures and layout directives

git-svn-id: https://svn.cs.ru.nl/repos/iTask-system/trunk@700 63da3aa8-80fd-4f01-9db8-e6ea747a3da2
parent c7b8b282
......@@ -1536,16 +1536,8 @@ Ext.reg("itasks.progress",itasks.form.ProgressField);
itasks.TaskCombinationPanel = Ext.extend(Ext.Panel, {
initComponent: function() {
Ext.apply(this, {
border: false,
layout: this.combination == "horizontal" ? "hbox" : null
border: false
});
//Set flex property for children of horizontal layouts
if(this.combination == "horizontal") {
for(var i = 0; i < this.items.length; i++) {
this.items[i].flex = 1;
}
}
itasks.TaskCombinationPanel.superclass.initComponent.apply(this,arguments);
},
update: function (data) {
......@@ -1577,12 +1569,6 @@ itasks.TaskCombinationPanel = Ext.extend(Ext.Panel, {
this.remove(items.length);
}
//Update flex for horizontal layouts
if(this.combination == "horizontal") {
for(var i = 0; i < items.length; i++) {
this.items.get(i).flex = 1;
}
}
this.doLayout();
}
});
......
This diff is collapsed.
......@@ -643,16 +643,8 @@ Ext.reg("itasks.progress",itasks.form.ProgressField);
itasks.TaskCombinationPanel = Ext.extend(Ext.Panel, {
initComponent: function() {
Ext.apply(this, {
border: false,
layout: this.combination == "horizontal" ? "hbox" : null
border: false
});
//Set flex property for children of horizontal layouts
if(this.combination == "horizontal") {
for(var i = 0; i < this.items.length; i++) {
this.items[i].flex = 1;
}
}
itasks.TaskCombinationPanel.superclass.initComponent.apply(this,arguments);
},
update: function (data) {
......@@ -684,12 +676,6 @@ itasks.TaskCombinationPanel = Ext.extend(Ext.Panel, {
this.remove(items.length);
}
//Update flex for horizontal layouts
if(this.combination == "horizontal") {
for(var i = 0; i < items.length; i++) {
this.items.get(i).flex = 1;
}
}
this.doLayout();
}
});
......
......@@ -16,7 +16,7 @@ import iTasks
import CommonDomain
//Additional imports for custom combinator creation
from TSt import applyTask, setCombination, mkSequenceTask, mkParallelTask
from TSt import applyTask, mkSequenceTask, mkParallelTask
from TSt import :: TSt{..}, :: TaskInfo{..}, :: StaticInfo{..}, :: Options{..}, :: Store, :: Config
from SessionDB import :: Session
from Types import :: ProcessId, :: TaskNr
......@@ -97,7 +97,6 @@ andTasksEnough:: ![LabeledTask a] -> (Task [a]) | iTask a
andTasksEnough taskCollection = mkParallelTask "andTasksEnough" andTasksEnough`
where
andTasksEnough` tst
# tst = setCombination TTVertical tst //Show parallel sub tasks in reversed order
# (_,tst =:{activated}) = applyTask (mkSequenceTask "enough" (applyTask (showMessage "Stop if enough results are returned..."))) tst
= applyTask (mkSequenceTask "tasks" (applyTask ((parallel "andTask" (\list -> length list >= 1 && activated) id id [t <<@ l \\(l,t) <- taskCollection])))) {tst & activated = True}
......@@ -38,7 +38,7 @@ addWarning msg =
dynamic (change msg) :: A.a: Change a | iTask a
where
change :: String TaskProperties (Task a) (Task a) -> (Maybe TaskProperties, Maybe (Task a), Maybe Dynamic) | iTask a
change msg props t t0 = (Nothing, Just (((showStickyMessage (redText msg) >>| getDefaultValue) -||- t) <<@ TTVertical), Just (addWarning msg))
change msg props t t0 = (Nothing, Just (((showStickyMessage (redText msg) >>| getDefaultValue) -||- t)), Just (addWarning msg))
redText msg = [DivTag [StyleAttr "color: red; font-size: 30px;"] [Text msg]]
......@@ -71,6 +71,6 @@ duplicateTask
//Utility
chooseProcess :: String -> Task ProcessId
chooseProcess question
= getProcesses [Active]
= getProcessesWithStatus [Active]
>>= \procs -> enterChoice question procs
>>= \proc -> return proc.Process.processId
\ No newline at end of file
......@@ -86,7 +86,7 @@ where
reassign wid
= selectUser "Who is next?"
>>= \who -> updateProcessOwner who wid
>>= \who -> setProcessOwner who wid
>>| return False
waitForIt wid
......
......@@ -225,7 +225,7 @@ getToName
cancel :: (Task a) -> Task a | iTask a
cancel task = task -||- (showMessage "Cancel this task" >>| getDefaultValue) <<@ TTVertical
cancel task = task -||- (showMessage "Cancel this task" >>| getDefaultValue)
orTasks2 :: [HtmlTag] [LabeledTask a] -> Task a | iTask a
orTasks2 msg tasks = parallel "orTasks2" (\list -> length list >= 1) hd undef [t <<@ l \\(l,t) <- tasks]
......
......@@ -12,7 +12,7 @@ yesOrNo :: [HtmlTag] (Task a) (Task a) -> Task a | iTask a
yesOrNo question yes no = requestConfirmation question >>= \yn -> if yn yes no
orTasksVert :: [Task a] -> Task a | iTask a
orTasksVert items = anyTask items <<@ TTVertical
orTasksVert items = anyTask items
OK :: Task Void
OK = enterInformation ""
\ No newline at end of file
......@@ -62,7 +62,7 @@ exit user
>>= \procs -> deleteAll [process.processId \\ process <- procs]
where
deleteAll [] = return Void
deleteAll [p:ps] = deleteProcessById p >>| deleteAll ps
deleteAll [p:ps] = deleteProcess p >>| deleteAll ps
newFile :: User -> Task Void
newFile user
......
definition module ProcessDBTasks
/**
* This module provides access to the process database
*/
import StdMaybe
from TSt import :: Task
from ProcessDB import :: ProcessStatus(..), :: Process(..)
from Types import :: UserId, :: ProcessId, :: ProcessRef, :: DynamicId, :: TaskId
from TaskTree import :: TaskProperties, :: TaskPriority, :: TaskProgress
from Time import :: Timestamp
from iTasks import class iTask
import GenPrint, GenParse, GenVisualize, GenUpdate
derive gVisualize ProcessRef, Process, ProcessStatus, TaskProperties, TaskPriority, TaskProgress, Timestamp
derive gUpdate ProcessRef, Process, ProcessStatus, TaskProperties, TaskPriority, TaskProgress, Timestamp
derive gPrint ProcessRef, Process, ProcessStatus, TaskProperties, TaskPriority, TaskProgress, Timestamp
derive gParse ProcessRef, Process, ProcessStatus, TaskProperties, TaskPriority, TaskProgress, Timestamp
//Allow either typed or untyped references to lookup a process table entry
class toProcessId a where toProcessId :: a -> ProcessId
instance toProcessId ProcessId
instance toProcessId (ProcessRef a)
/**
* Retrieves a Process record from the process table
*
* @param The process id
*
* @return When found, the Process record. Nothing when the process can not be found.
*/
getProcess :: !pid -> Task (Maybe Process) | toProcessId pid
/**
* Retrieves a Process record with an additional check on the process owner. Only
* when the process is owned by the indicated user it will be returned.
*
* @param The owner of the indicated process
* @param The process id
*
* @return When found, the Process record. Nothing when the process can not be found.
*/
getProcessForUser :: !UserId !pid -> Task (Maybe Process) | toProcessId pid
/**
* Retrieves the processes with indicated process ids
*
* @param A list of process ids to match on
*
* @return The list of found processes
*/
getProcesses :: ![pid] -> Task [Process] | toProcessId pid
/**
* Retrieves all process that have one of the given statuses
*
* @param A list of statuses to match on
*
* @return The list of processes having the given statuses
*/
getProcessesWithStatus :: ![ProcessStatus] -> Task [Process]
/**
* Retrieves the processes that are owned by indicated user and have one of the
* given statuses.
*
* @param A process owner to match on
* @param A list of statuses to match on
* @param Ignore embedded processes
*
* @return The list of found processes
*/
getProcessesForUser :: !UserId ![ProcessStatus] -> Task [Process]
/**
* Poll who is the owner of a process.
*
* @param The process reference
*
* @return A task that yields the owner if the referenced process is not deleted
*/
getProcessOwner :: !pid -> Task (Maybe UserId) | toProcessId pid
/**
* Changes the owner of the indicated process. The current user is automatically set
* as delegator of the process.
*
* @param The new process owner
* @param The process id
*
* @return True when the process is updated, False if the process was not found.
*/
setProcessOwner :: !UserId !pid -> Task Bool | toProcessId pid
/**
* Poll the status of a process.
*
* @param The process reference
*
* @return A task that yields the status of the referenced process
*/
getProcessStatus :: !pid -> Task ProcessStatus | toProcessId pid
/**
* Change the process status to Active
*
* @param The process reference
*
* @return A task that yields True when the process was successfully activated
* and False when the process could not be found.
*/
activateProcess :: !pid -> Task Bool | toProcessId pid
/**
* Change the process status to suspended.
* The tasks within this process will be inaccessible until the process is activated again.
*
* @param The process reference
*
* @return A task that yields True when the process was successfully suspended
* and False when the process could not be found.
*/
suspendProcess :: !pid -> Task Bool | toProcessId pid
/**
* Delete a process from the process database
* Once a process is deleted all of its results are lost.
*
* @param The process reference
*
* @return A task that yields True when the process was successfully deleted
* and False when the process could not be found.
*/
deleteProcess :: pid -> Task Bool | toProcessId pid
implementation module ProcessDBTasks
import StdOverloaded, StdClass, StdInt, StdArray, StdTuple, StdList, GenBimap
import TSt
from ProcessDB import :: Process{..}, :: ProcessStatus(..)
from ProcessDB import qualified class ProcessDB(..)
from ProcessDB import qualified instance ProcessDB TSt
from UserDB import getUser
from Types import :: ProcessId, :: ProcessRef, :: UserId
import Time
import CommonCombinators
import Store
derive gVisualize ProcessRef, Process, ProcessStatus, TaskProperties, TaskSystemProperties, TaskManagerProperties, TaskWorkerProperties, TaskPriority, TaskProgress, Timestamp
derive gUpdate ProcessRef, Process, ProcessStatus, TaskProperties, TaskSystemProperties, TaskManagerProperties, TaskWorkerProperties, TaskPriority, TaskProgress, Timestamp
derive gPrint ProcessRef, Process, ProcessStatus, TaskProperties, TaskSystemProperties, TaskManagerProperties, TaskWorkerProperties, TaskPriority, TaskProgress, Timestamp
derive gParse ProcessRef, Process, ProcessStatus, TaskProperties, TaskSystemProperties, TaskManagerProperties, TaskWorkerProperties, TaskPriority, TaskProgress, Timestamp
class toProcessId a where toProcessId :: a -> ProcessId
instance toProcessId ProcessId
where
toProcessId pid = pid
instance toProcessId (ProcessRef a)
where
toProcessId (ProcessRef pid) = pid
getProcess :: !pid -> Task (Maybe Process) | toProcessId pid
getProcess pid = mkInstantTask "getProcess" (\tst -> ProcessDB@getProcess (toProcessId pid) tst)
getProcessForUser :: !UserId !pid -> Task (Maybe Process) | toProcessId pid
getProcessForUser uid pid = mkInstantTask "getProcessForUser" (\tst -> ProcessDB@getProcessForUser uid (toProcessId pid) tst)
getProcesses :: ![pid] -> Task [Process] | toProcessId pid
getProcesses ids = mkInstantTask "getProcessesById" (\tst -> ProcessDB@getProcessesById (map toProcessId ids) tst)
getProcessesWithStatus :: ![ProcessStatus] -> Task [Process]
getProcessesWithStatus statuses = mkInstantTask "getProcesses" (\tst -> ProcessDB@getProcesses statuses tst)
getProcessesForUser :: !UserId ![ProcessStatus] -> Task [Process]
getProcessesForUser uid statuses = mkInstantTask "getProcessesForUser" (\tst -> ProcessDB@getProcessesForUser uid statuses tst)
getProcessOwner :: !pid -> Task (Maybe UserId) | toProcessId pid
getProcessOwner pid = mkInstantTask "getProcess" getProcessStatus`
where
getProcessStatus` tst
# (process,tst) = ProcessDB@getProcess (toProcessId pid) tst
# owner = if (isNothing process) Nothing (Just (fst (fromJust process).properties.managerProps.worker))
= (owner,tst)
setProcessOwner :: !UserId !pid -> Task Bool | toProcessId pid
setProcessOwner uid pid = mkInstantTask "setProcessOwner" setProcessOwner`
where
setProcessOwner` tst
# (cur,tst) = getCurrentUser tst //Current user is the new delegator of the process
# (user,tst) = getUser uid tst
# (delegator,tst) = getUser cur tst
= ProcessDB@setProcessOwner (user.User.userId,user.User.displayName) (delegator.User.userId,delegator.User.displayName) (toProcessId pid) tst
getProcessStatus :: !pid -> Task ProcessStatus | toProcessId pid
getProcessStatus pid = mkInstantTask "getProcessStatus" getProcessStatus`
where
getProcessStatus` tst
# (mbProcess,tst) = ProcessDB@getProcess (toProcessId pid) tst
= case mbProcess of
Just {Process | status} = (status, tst)
Nothing = (Deleted, tst)
activateProcess :: !pid -> Task Bool | toProcessId pid
activateProcess pid = mkInstantTask "activateProcess" activateProcess`
where
activateProcess` tst = ProcessDB@setProcessStatus Active (toProcessId pid) tst
suspendProcess :: !pid -> Task Bool | toProcessId pid
suspendProcess pid = mkInstantTask "suspendProcess" suspendProcess`
where
suspendProcess` tst = ProcessDB@setProcessStatus Suspended (toProcessId pid) tst
deleteProcess :: pid -> Task Bool | toProcessId pid
deleteProcess pid = mkInstantTask "deleteProcess" deleteProcess`
where
deleteProcess` tst = ProcessDB@deleteProcess (toProcessId pid) tst
definition module SessionDBTasks
from SessionDB import :: Session
from UserDB import :: User
from TSt import :: Task
from Types import :: SessionId, :: Session, :: User
from iTasks import class iTask
import GenPrint, GenParse, GenVisualize, GenUpdate
......@@ -21,4 +20,4 @@ createSession :: !User -> Task Session
*
* @param The session identifier
*/
destroySession :: !String -> Task Void
\ No newline at end of file
destroySession :: !SessionId -> Task Void
\ No newline at end of file
implementation module SessionDBTasks
from SessionDB import :: Session
from Types import :: SessionId, :: Session, :: User
from SessionDB import qualified createSession
from SessionDB import qualified destroySession
from UserDB import :: User
from TSt import :: TSt, :: Task
from TSt import mkInstantTask
from iTasks import class iTask
import GenPrint, GenParse, GenVisualize, GenUpdate
createSession :: !User -> Task Session
createSession user = mkInstantTask "createSession" (SessionDB@createSession user)
destroySession :: !String -> Task Void
destroySession :: !SessionId -> Task Void
destroySession sessionId = mkInstantTask "destroySession" (\tst -> (Void, SessionDB@destroySession sessionId tst))
\ No newline at end of file
......@@ -3,17 +3,48 @@ definition module SystemTasks
* This module provides tasks for interacting with the iTasks engine
*/
from TSt import :: Task
from UserDB import :: User
from Types import :: UserId, :: User, :: ProcessId, :: ProcessRef
from iTasks import class iTask
import GenPrint, GenParse, GenVisualize, GenUpdate
/**
* Returns the user currently logged in the iTask system
*
* @return The current user
*/
getCurrentUser :: Task User
/**
* Get default value
* Retrieves the process id of the current process
*
* @return The process id of the current process
*/
getCurrentProcessId :: Task ProcessId
/**
* Compute a default value
*
* @return The default value
*/
getDefaultValue :: Task a | iTask a
/**
* Create a new process.
*
* @param The user that will perform processes main task.
* @param Activate the process immediately (False creates the process in a suspended state)
*
* @return A reference to the newly created process
*/
spawnProcess :: !UserId !Bool !(Task a) -> Task (ProcessRef a) | iTask a
/**
* Wait (blocking) for a process to complete.
*
* @param The process reference
*
* @return A task that maybe gives the result of the process.
* When a process is prematurely deleted, the task yields Nothing
*/
waitForProcess :: (ProcessRef a) -> Task (Maybe a) | iTask a
\ No newline at end of file
implementation module SystemTasks
from TSt import :: Task, :: TSt
from TSt import mkInstantTask
from TSt import accWorldTSt
from TSt import :: Task, :: TSt(..), :: Store, :: HTTPRequest, :: Config
from TSt import :: ChangeLifeTime, :: StaticInfo(..), :: Options, :: Workflow
from TSt import mkInstantTask, mkMonitorTask
from TSt import accWorldTSt, loadProcessResult, taskLabel, taskNrFromString
from TSt import qualified getCurrentUser
from TSt import qualified createTaskInstance
import Types
from TaskTree import :: TaskTree, :: TaskInfo, ::TaskProperties, :: TaskManagerProperties(..), :: TaskPriority(..)
from Time import :: Timestamp
from UserDB import :: User, :: UserId
from UserDB import qualified getUser
from ProcessDB import :: Process{..}, :: ProcessStatus(..)
from ProcessDB import qualified class ProcessDB(..)
from ProcessDB import qualified instance ProcessDB TSt
from DynamicDB import :: DynamicId
from DynamicDB import qualified class DynamicDB(..)
from DynamicDB import qualified instance DynamicDB TSt
from iTasks import class iTask
import GenPrint, GenParse, GenVisualize, GenUpdate
......@@ -18,8 +33,46 @@ where
# (cur,tst) = TSt@getCurrentUser tst
= UserDB@getUser cur tst
getCurrentProcessId :: Task ProcessId
getCurrentProcessId = mkInstantTask "getCurrentProcessId" getCurrentProcessId`
where
getCurrentProcessId` tst=:{staticInfo}
= (staticInfo.currentProcessId,tst)
getDefaultValue :: Task a | iTask a
getDefaultValue = mkInstantTask "getDefaultValue" getDefaultValue`
where
getDefaultValue` tst
= accWorldTSt defaultValue tst
spawnProcess :: !UserId !Bool !(Task a) -> Task (ProcessRef a) | iTask a
spawnProcess uid activate task = mkInstantTask "spawnProcess" spawnProcess`
where
spawnProcess` tst=:{TSt|mainTask}
# (curUid,tst) = TSt@getCurrentUser tst
# (user,tst) = UserDB@getUser uid tst
# properties =
{ TaskManagerProperties
| worker = (user.User.userId,user.User.displayName)
, subject = taskLabel task
, priority = NormalPriority
, deadline = Nothing
}
# (pid,tst) = TSt@createTaskInstance task properties True tst
= (ProcessRef pid, {tst & activated = True})
waitForProcess :: (ProcessRef a) -> Task (Maybe a) | iTask a
waitForProcess (ProcessRef pid) = mkMonitorTask "waitForProcess" waitForProcess`
where
waitForProcess` tst
# (mbProcess,tst) = ProcessDB@getProcess pid tst
= case mbProcess of
Just {Process | processId, status}
= case status of
Finished
# (mbResult,tst) = loadProcessResult (taskNrFromString pid) tst
= (mbResult,{tst & activated = True})
_
= (Nothing, {tst & activated = False}) // We are not done yet...
_
= (Nothing, {tst & activated = True}) //We could not find the process in our database, we are done
......@@ -16,13 +16,13 @@ determineRPCItems forest tst = (flatten [determineTreeRPCItems tree \\ tree <- f
determineTreeRPCItems :: !TaskTree -> [RPCExecute]
determineTreeRPCItems (TTMainTask ti mti children)
| (not ti.TaskInfo.active) || ti.TaskInfo.finished= []
| (not ti.TaskInfo.active) = []
| otherwise = flatten [(determineTreeRPCItems child) \\ child <- children]
determineTreeRPCItems (TTParallelTask ti tc children)
| (not ti.TaskInfo.active) || ti.TaskInfo.finished = []
determineTreeRPCItems (TTParallelTask ti children)
| (not ti.TaskInfo.active) = []
| otherwise = flatten [(determineTreeRPCItems child) \\ child <- children]
determineTreeRPCItems (TTSequenceTask ti children)
| (not ti.TaskInfo.active) || ti.TaskInfo.finished = []
| (not ti.TaskInfo.active) = []
| otherwise = flatten [(determineTreeRPCItems child) \\ child <- children]
determineTreeRPCItems (TTRpcTask ti rpci) = [rpci]
determineTreeRPCItems _ = []
......
......@@ -104,7 +104,6 @@ where
:: CombinationPanel =
{ xtype :: String
, taskId :: String
, combination :: String
, items :: [TaskPanel]
}
......@@ -136,35 +135,21 @@ buildTaskPanel (TTRpcTask ti rpc)
buildTaskPanel (TTMainTask ti mti _)
= MainTaskPanel {MainTaskPanel | xtype = "itasks.task-waiting", taskId = ti.TaskInfo.taskId, properties = mti}
buildTaskPanel (TTSequenceTask ti tasks)
| ti.TaskInfo.finished = TaskDone
| otherwise = case [t \\ t <- tasks | isActive t] of
= case [t \\ t <- tasks | isActive t] of
[] = if (allFinished tasks) TaskDone TaskRedundant
[t] = buildTaskPanel t
_ = (abort "Multiple simultaneously active tasks in a sequence!")
buildTaskPanel (TTParallelTask ti TTHorizontal tasks)
= CombinationPanel {CombinationPanel| xtype = "itasks.task-combination", taskId = ti.TaskInfo.taskId, combination = "horizontal", items = [buildTaskPanel t \\ t <- tasks | isActive t]}
buildTaskPanel (TTParallelTask ti TTVertical tasks)
= CombinationPanel {CombinationPanel| xtype = "itasks.task-combination", taskId = ti.TaskInfo.taskId, combination = "vertical", items = [buildTaskPanel t \\ t <- tasks | isActive t]}
buildTaskPanel (TTParallelTask ti tasks)
= CombinationPanel {CombinationPanel| xtype = "itasks.task-combination", taskId = ti.TaskInfo.taskId, items = [buildTaskPanel t \\ t <- tasks | isActive t]}
buildTaskPanel (TTFinishedTask _)
= TaskDone
taskOverview :: [HtmlTag] [TaskTree] -> [HtmlTag]
taskOverview prompt branches =
[ DivTag [ClassAttr "it-display"] prompt
, DivTag [ClassAttr "it-task-overview"]
[TableTag [] [TrTag [] [TdTag [] [icon info.TaskInfo.finished],TdTag [] [Text info.TaskInfo.taskLabel]] \\ (TTSequenceTask info _) <- branches]]
]
where
icon True = DivTag [ClassAttr "it-task-overview-icon icon-finishedTask"] []
icon False = DivTag [ClassAttr "it-task-overview-icon icon-editTask"] []