diff --git a/Examples/Distributed/.gitignore b/Examples/Distributed/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1e107f52e4702b33a7bed7c76d591f4b14fe36ff --- /dev/null +++ b/Examples/Distributed/.gitignore @@ -0,0 +1 @@ +examples diff --git a/Examples/Distributed/examples.icl b/Examples/Distributed/examples.icl index 0efe193e2fb2bd3d77891bb2154ecef82f2e58fb..b6a7bebf20a5a6bbb1d5793b7d8c76d6ca5c373e 100755 --- a/Examples/Distributed/examples.icl +++ b/Examples/Distributed/examples.icl @@ -99,8 +99,7 @@ getDomain startMode :: String -> Task () startMode executable - = startDistributedEngine executable - >>| get serverRoleShare + = get serverRoleShare >>- \role = case role of DomainServer domain -> startAuthEngine domain >>| loginAndManageWorkList "Service engineer application" (myTasks True) Server domain -> startAuthEngine domain >>| loginRemote (myTasks False) @@ -141,6 +140,6 @@ Start world = startEngineWithOptions opts [ publish "/" (\_-> startMode (IF_WINDOWS "examples.exe" "examples")) ] world where - opts [] = \op->(Just op, ["Started server on port: " +++ toString op.serverPort]) + opts [] = \op->(Just {op&distributed=True}, ["Started server on port: " +++ toString op.serverPort]) opts ["-p",p:as] = appFst (fmap (\o->{o & serverPort=toInt p})) o opts as opts [a:as] = opts as diff --git a/Libraries/iTasks/Engine.dcl b/Libraries/iTasks/Engine.dcl index 21fda17c1ee66d0f5a4220be6c801d7f3edd53b6..2cd7adad6d5352b7d952fbb902f66aadec9b73f6 100644 --- a/Libraries/iTasks/Engine.dcl +++ b/Libraries/iTasks/Engine.dcl @@ -23,6 +23,7 @@ import iTasks.WF.Definition , persistTasks :: Bool , autoLayout :: Bool , timeout :: Maybe Int // The timeout + , distributed :: Bool , webDirPath :: FilePath // Location of public files that are served by the iTask webserver , storeDirPath :: FilePath // Location of the application's persistent data files , tempDirPath :: FilePath // Location for temporary files used in tasks diff --git a/Libraries/iTasks/Engine.icl b/Libraries/iTasks/Engine.icl index ce1db7abe562959998244c0a001be140a9bb0895..97a505444ff7327c6bac57116c6ef2a18f7feefe 100644 --- a/Libraries/iTasks/Engine.icl +++ b/Libraries/iTasks/Engine.icl @@ -25,6 +25,7 @@ import iTasks.Internal.IWorld, iTasks.Internal.TaskEval, iTasks.Internal.TaskSto import iTasks.Internal.Util import iTasks.Internal.TaskServer import iTasks.Internal.EngineTasks +import iTasks.Internal.Distributed.Symbols from iTasks.Extensions.DateTime import toDate, toTime, instance == Date, instance == Time @@ -44,14 +45,23 @@ defaultEngineOptions world # options = { appName = appName , appPath = appPath - , appVersion = appVersion + , appVersion = appVersion , serverPort = IF_POSIX_OR_WINDOWS 8080 80 +<<<<<<< HEAD , serverUrl = "http://localhost/" , keepaliveTime = {tv_sec=300,tv_nsec=0} // 5 minutes , sessionTime = {tv_sec=60,tv_nsec=0} // 1 minute, (the client pings every 10 seconds by default) , persistTasks = False , autoLayout = True , timeout = Just 500 +======= + , serverUrl = "http://localhost/" + , keepaliveTime = 300 // 5 minutes + , sessionTime = 60 // 1 minute, (the client pings every 10 seconds by default) + , persistTasks = False + , autoLayout = True + , distributed = False +>>>>>>> Add storing symbols to the engine , webDirPath = appDir appName +++ "-www" , storeDirPath = appDir appName +++ "-data" "stores" , tempDirPath = appDir appName +++ "-data" "tmp" @@ -133,6 +143,8 @@ startEngineWithOptions initFun publishable world # iworld = createIWorld (fromJust mbOptions) world # (res,iworld) = initJSCompilerState iworld | res =:(Error _) = show ["Fatal error: " +++ fromError res] (destroyIWorld iworld) + # (_, iworld) = if options.distributed (storeSymbols options.appName iworld) (Ok "", iworld) + | res =:(Error _) = show ["Fatar error: " +++ fromError res] (destroyIWorld iworld) # iworld = serve [TaskWrapper removeOutdatedSessions] (tcpTasks options.serverPort options.keepaliveTime) (timeout options.timeout) iworld = destroyIWorld iworld where diff --git a/Libraries/iTasks/Extensions/Distributed/Engine.icl b/Libraries/iTasks/Extensions/Distributed/Engine.icl deleted file mode 100644 index 66c1998e1cdc4e38939c30702bc4cfa36b66eb94..0000000000000000000000000000000000000000 --- a/Libraries/iTasks/Extensions/Distributed/Engine.icl +++ /dev/null @@ -1,59 +0,0 @@ -implementation module iTasks.Extensions.Distributed.Engine - -from iTasks.WF.Tasks.Core import accWorld -from iTasks.Internal.SDS import read, write -import symbols_in_program -from iTasks.Internal.IWorld import :: IWorld{world} -from Data.Error import :: MaybeError(..) -from iTasks.WF.Definition import :: TaskException, :: Task(..), :: TaskResult, :: TaskEvalOpts, :: Event(..), :: Set -from iTasks.Internal.Task import mkInstantTask -from iTasks.Internal.TaskState import :: TaskTree -from iTasks.WF.Definition import class iTask -from iTasks.Internal.SDS import :: ReadWriteShared, :: RWShared, :: Shared -from iTasks.WF.Definition import :: Task, generic gEq, generic gDefault, generic JSONDecode, generic JSONEncode, generic gText, generic gEditor, :: Editor, :: TaskId -from Data.Maybe import :: Maybe -from Text.JSON import :: JSONNode, generic JSONEncode, generic JSONDecode -from iTasks.Internal.Generic.Visualization import :: TextFormat(..) -import StdFile -import dynamic_string -import Text.Encodings.Base64 -from iTasks.WF.Combinators.Common import @!, >>- -from iTasks.WF.Tasks.SDS import set -from iTasks.SDS.Sources.Store import :: SDS, sharedStore -import StdTuple - -symbolsShare :: Shared String -symbolsShare = sharedStore "symbols" "" - -startDistributedEngine :: String -> Task () -startDistributedEngine executable = storeSymbols executable - -storeSymbols :: String -> Task () -storeSymbols file = mkInstantTask eval -where - eval taskId iworld=:{IWorld|world} - # (symbols, world) = accFiles (read_symbols file) world - # iworld = {IWorld| iworld & world = world} - # val = base64Encode (copy_to_string symbols) - # (res,iworld) = write val symbolsShare iworld - = case res of - Ok _ = (Ok (), iworld) - Error e = (Error e, iworld) - -accSymbols :: ({#Symbol} -> a) -> Task a | iTask a -accSymbols fun = mkInstantTask eval -where - eval taskId iworld - # (val, iworld) = read symbolsShare iworld - = case val of - Ok val = (Ok (fun (fst (copy_from_string (base64Decode val)))), iworld) - Error e = (Error e, iworld) - -withSymbols :: ({#Symbol} -> Task a) -> Task a | iTask a -withSymbols taskfun = Task eval -where - eval event evalOpts state iworld - # (val, iworld) = read symbolsShare iworld - = case val of - Ok val = let (Task eval`) = taskfun (fst (copy_from_string (base64Decode val))) in eval` event evalOpts state iworld - diff --git a/Libraries/iTasks/Extensions/Distributed/Instance.icl b/Libraries/iTasks/Extensions/Distributed/Instance.icl index e42002e791626e4aba4d2d43fd8665866e13defb..631edc78acc6641dfd8da5478ec2f7808f649001 100644 --- a/Libraries/iTasks/Extensions/Distributed/Instance.icl +++ b/Libraries/iTasks/Extensions/Distributed/Instance.icl @@ -10,7 +10,7 @@ import iTasks.Extensions.Distributed._Formatter import iTasks.Extensions.Distributed._Util import iTasks.Extensions.Distributed._Types import iTasks.Extensions.Distributed._SDS -import iTasks.Extensions.Distributed.Engine +import iTasks.Internal.Distributed.Symbols import iTasks.Extensions.Distributed._Evaluation from iTasks.Extensions.Distributed.Task import :: Domain(..) from iTasks.Extensions.Distributed._Util import repeatClient diff --git a/Libraries/iTasks/Extensions/Distributed/RemoteTask.icl b/Libraries/iTasks/Extensions/Distributed/RemoteTask.icl index 36c4a82a9672d1c01d09b11541ddc582c8b8c54e..f3c8e2d1e3b7a0fb454f90b62b6644098b278f64 100644 --- a/Libraries/iTasks/Extensions/Distributed/RemoteTask.icl +++ b/Libraries/iTasks/Extensions/Distributed/RemoteTask.icl @@ -12,7 +12,6 @@ import iTasks.Extensions.Distributed._Types import iTasks.Extensions.Distributed.Instance import iTasks.Extensions.Distributed._SDS import iTasks.Extensions.Distributed._Attributes -import iTasks.Extensions.Distributed.Engine from iTasks.Extensions.Distributed.Task import :: Domain(..) remoteAssignTask :: !TaskAttributes (Task a) Domain -> Task a | iTask a diff --git a/Libraries/iTasks/Extensions/Distributed/Task.icl b/Libraries/iTasks/Extensions/Distributed/Task.icl index 1c910c711dabab70078ba93ee2238fa2d2277896..2fee8a6d05384aad7f5a223b70f557346d4f3532 100644 --- a/Libraries/iTasks/Extensions/Distributed/Task.icl +++ b/Libraries/iTasks/Extensions/Distributed/Task.icl @@ -20,7 +20,7 @@ from iTasks.Extensions.User import currentUser, :: User(..), :: UserTitle, :: Ro from iTasks.Internal.SDS import :: SDS, :: ReadWriteShared, :: RWShared, :: ReadOnlyShared, :: ROShared from iTasks.Extensions.Distributed.Authentication import currentDomain import qualified iTasks.WF.Tasks.SDS as C -import iTasks.Extensions.Distributed.Engine +import iTasks.Internal.Distributed.Symbols instance @: worker (Task a) | iTask a & toUserConstraint worker where diff --git a/Libraries/iTasks/Extensions/Distributed/_SDS.icl b/Libraries/iTasks/Extensions/Distributed/_SDS.icl index fd5a7f20d52751ae6aa2e5b6105af23cc136312c..3b2ba113625392561b878f9a5cfede0edaa49f2a 100644 --- a/Libraries/iTasks/Extensions/Distributed/_SDS.icl +++ b/Libraries/iTasks/Extensions/Distributed/_SDS.icl @@ -8,7 +8,7 @@ import iTasks.Extensions.Distributed.Instance import iTasks.Extensions.Distributed._Attributes import qualified Data.Map as DM import Text.Encodings.Base64 -import iTasks.Extensions.Distributed.Engine +import iTasks.Internal.Distributed.Symbols from iTasks.Internal.Serialization import dynamicJSONEncode, dynamicJSONDecode from iTasks.UI.Editor.Common import emptyEditor diff --git a/Libraries/iTasks/Extensions/Distributed/iTasks.dcl b/Libraries/iTasks/Extensions/Distributed/iTasks.dcl index adcaa2cca73e2706934b96cedfa659aa895e3bbd..62c1e2af5491c58d5a063c4a70be9304e762f7b9 100644 --- a/Libraries/iTasks/Extensions/Distributed/iTasks.dcl +++ b/Libraries/iTasks/Extensions/Distributed/iTasks.dcl @@ -22,7 +22,7 @@ from iTasks.SDS.Sources.System import currentDateTime from iTasks.Extensions.User import currentUser, :: User(..), :: UserTitle, :: Role, :: UserId, assign, workerAttributes, :: Password, :: Username, workAs, :: Credentials{..}, users from iTasks.SDS.Definition import :: ReadWriteShared, :: RWShared, :: ReadOnlyShared from iTasks.WF.Tasks.Core import accWorld -from iTasks.Extensions.Distributed.Engine import startDistributedEngine +import iTasks.Internal.Distributed.Symbols from iTasks.Extensions.Distributed.Instance import instanceServer, instanceClient, instanceFilter, instanceClameFilter from Data.Map import :: Map from iTasks.Extensions.Admin.WorkflowAdmin import workflow, class toWorkflow(..), :: Workflow, publish, :: PublishedTask{..}, :: TaskWrapper(..), manageWorklist, instance toWorkflow (Task a), instance toWorkflow (WorkflowContainer a), instance toWorkflow (a -> Task b), instance toWorkflow (ParamWorkflowContainer a b), :: WorkflowContainer, :: ParamWorkflowContainer diff --git a/Libraries/iTasks/Internal/Client/RunOnClient.icl b/Libraries/iTasks/Internal/Client/RunOnClient.icl index 3686f7a379a2d03603ca1d4eb0279066e1590a2d..807fbb33890b6ef89d2455fdb950a3f3a549ba64 100644 --- a/Libraries/iTasks/Internal/Client/RunOnClient.icl +++ b/Libraries/iTasks/Internal/Client/RunOnClient.icl @@ -131,6 +131,7 @@ createClientIWorld serverURL currentInstance , persistTasks = False , autoLayout = True , timeout = Just 100 + , distributed = False , webDirPath = locundef "webDirectory" , storeDirPath = locundef "dataDirectory" , tempDirPath = locundef "tempDirectory" diff --git a/Libraries/iTasks/Extensions/Distributed/Engine.dcl b/Libraries/iTasks/Internal/Distributed/Symbols.dcl similarity index 66% rename from Libraries/iTasks/Extensions/Distributed/Engine.dcl rename to Libraries/iTasks/Internal/Distributed/Symbols.dcl index 959c05389c44726a4cea54532405a47aac804c91..91128ab49eed64506b1111065c839f792df0b591 100644 --- a/Libraries/iTasks/Extensions/Distributed/Engine.dcl +++ b/Libraries/iTasks/Internal/Distributed/Symbols.dcl @@ -1,4 +1,4 @@ -definition module iTasks.Extensions.Distributed.Engine +definition module iTasks.Internal.Distributed.Symbols from iTasks.WF.Definition import class iTask from iTasks.WF.Definition import :: Task, generic gEq, generic gDefault, generic JSONDecode, generic JSONEncode, generic gText, generic gEditor, :: Editor @@ -6,13 +6,11 @@ from Data.Maybe import :: Maybe from Text.JSON import :: JSONNode, generic JSONEncode, generic JSONDecode from iTasks.Internal.Generic.Visualization import :: TextFormat(..) from symbols_in_program import :: Symbol +from iTasks.Internal.IWorld import :: IWorld +from Data.Error import :: MaybeError +from iTasks.WF.Definition import :: TaskException -/* - * Start the distributed iTasks engine. - * - * @param executable Path to executable (or library) containing the code of this server. - */ -startDistributedEngine :: String -> Task () +storeSymbols :: String !*IWorld -> (MaybeError TaskException String, !*IWorld) accSymbols :: ({#Symbol} -> a) -> Task a | iTask a diff --git a/Libraries/iTasks/Internal/Distributed/Symbols.icl b/Libraries/iTasks/Internal/Distributed/Symbols.icl new file mode 100644 index 0000000000000000000000000000000000000000..50ce725394a16047f8ca87d41d6caf58016f44b1 --- /dev/null +++ b/Libraries/iTasks/Internal/Distributed/Symbols.icl @@ -0,0 +1,58 @@ +implementation module iTasks.Internal.Distributed.Symbols + +import iTasks + +import StdFile +//from iTasks.WF.Tasks.Core import accWorld +//from iTasks.Internal.SDS import read, write +import symbols_in_program +//from iTasks.Internal.IWorld import :: IWorld{world} +//from Data.Error import :: MaybeError(..) +//from iTasks.WF.Definition import :: TaskException, :: Task(..), :: TaskResult, :: TaskEvalOpts, :: Event(..), :: Set +//from iTasks.Internal.Task import mkInstantTask +//from iTasks.Internal.TaskState import :: TaskTree +//from iTasks.WF.Definition import class iTask +//from iTasks.Internal.SDS import :: ReadWriteShared, :: RWShared, :: Shared +//from iTasks.WF.Definition import :: Task, generic gEq, generic gDefault, generic JSONDecode, generic JSONEncode, generic gText, generic gEditor, :: Editor, :: TaskId +//from Data.Maybe import :: Maybe +//from Text.JSON import :: JSONNode, generic JSONEncode, generic JSONDecode +//from iTasks.Internal.Generic.Visualization import :: TextFormat(..) +//import StdFile +import dynamic_string +import Text.Encodings.Base64 + +import iTasks.Internal.SDS +import iTasks.Internal.Task +import iTasks.Internal.IWorld +//from iTasks.WF.Combinators.Common import @!, >>- +//from iTasks.WF.Tasks.SDS import set +//from iTasks.SDS.Sources.Store import :: SDS, sharedStore +//import StdTuple + +symbolsShare :: Shared String +symbolsShare = sharedStore "symbols" "" + +storeSymbols :: String !*IWorld -> (MaybeError TaskException String, !*IWorld) +storeSymbols file iworld +# (symbols, iworld) = accFiles (read_symbols file) iworld +# val = base64Encode (copy_to_string symbols) +# (res, iworld) = write val symbolsShare iworld +| isError res = (liftError res, iworld) += (Ok val, iworld) + +accSymbols :: ({#Symbol} -> a) -> Task a | iTask a +accSymbols fun = mkInstantTask eval +where + eval taskId iworld + # (val, iworld) = read symbolsShare iworld + = case val of + Ok val = (Ok (fun (fst (copy_from_string (base64Decode val)))), iworld) + Error e = (Error e, iworld) + +withSymbols :: ({#Symbol} -> Task a) -> Task a | iTask a +withSymbols taskfun = Task eval +where + eval event evalOpts state iworld + # (val, iworld) = read symbolsShare iworld + = case val of + Ok val = let (Task eval`) = taskfun (fst (copy_from_string (base64Decode val))) in eval` event evalOpts state iworld diff --git a/Libraries/iTasks/Internal/IWorld.dcl b/Libraries/iTasks/Internal/IWorld.dcl index d6e1e817dc8e2c479bcc04a87228907bfa9ea6e4..2c5d575ee14e94575a8e90841668458eede83e85 100644 --- a/Libraries/iTasks/Internal/IWorld.dcl +++ b/Libraries/iTasks/Internal/IWorld.dcl @@ -6,7 +6,7 @@ from Data.Maybe import :: Maybe from Data.Error import :: MaybeError(..), :: MaybeErrorString(..) from Data.Set import :: Set from Data.Queue import :: Queue -from StdFile import class FileSystem +from StdFile import class FileSystem, class FileEnv from System.Time import :: Timestamp, :: Timespec from Text.GenJSON import :: JSONNode from iTasks.Engine import :: EngineOptions @@ -161,3 +161,4 @@ iworldLocalDateTime` :: !*IWorld -> (!DateTime, !*IWorld) iworldResource :: (*Resource -> (Bool, *Resource)) *IWorld -> (*[*Resource], *IWorld) instance FileSystem IWorld +instance FileEnv IWorld diff --git a/Libraries/iTasks/Internal/IWorld.icl b/Libraries/iTasks/Internal/IWorld.icl index 3c474aba6879bd5d3abd3fb66599090f96935427..670055a7704a3d2d4dd6a2a4450e42ee0f35880e 100644 --- a/Libraries/iTasks/Internal/IWorld.icl +++ b/Libraries/iTasks/Internal/IWorld.icl @@ -15,8 +15,8 @@ import Data.Integer import iTasks.SDS.Combinators.Common -from StdFile import class FileSystem(..) -from StdFile import instance FileSystem World +from StdFile import class FileSystem(..), class FileEnv(..), :: Files +from StdFile import instance FileSystem World, instance FileEnv World from StdFunc import const, o, seqList, :: St from StdMisc import abort from StdOrdList import sortBy @@ -185,3 +185,12 @@ where sfopen filename mode iworld=:{IWorld|world} # (ok,file,world) = sfopen filename mode world = (ok,file,{IWorld|iworld & world = world}) + +instance FileEnv IWorld +where + accFiles accfun iworld=:{IWorld|world} + # (x, world) = accFiles accfun world + = (x, {IWorld | iworld & world=world}) + appFiles appfun iworld=:{IWorld|world} + # world = appFiles appfun world + = {IWorld | iworld & world=world}