Create Workspace
Create User/Login/App Workspaces
Content
Principles and Processes
Commands
Projectors
Additional Information
Principles
AppWorkspaces are created by system when an App is deployed to a Cluster.
Workspaces of other kinds must be explicitely created (and initialized).
It is not possible to work with uninitialized workspaces.
Client calls
c.registry.CreateLogin
using pseudo WS calculated as (main cluster, crc16(login))If router sees that baseWSID of WSID is < MaxPseudoBaseWSID then it replaces that pseudo base WSID with app base WSID:
(main cluser, (baseWSID %% numAppWorkspaces) + FirstBaseAppWSID)
crc16 = crc32.ChecksumIEEE & (MaxUint32 >> 16)
cdoc.registry.Login
stores login hash only
Create Login
FIXME: cdoc.sys.WorkspaceID is a large collection, must be wdoc.sys.WorkspaceID
c.registry.CreateLogin()
sys/registry
pseudoWS
main
cdoc.registry.Login (owner) aproj.sys.InvokeCreateWorkspaceID
sys/registry
app ws
main
c.sys.CreateWorkspaceID() cdoc.sys.WorkspaceID aproj.sys.InvokeCreateWorkspace()
Target App
(Target Cluster, base App WSID)
Target Cluster
c.sys.CreateWorkspace() cdoc.sys.WorkspaceDescriptor cdoc.sys.UserProfile/DeviceProfile aproj.sys.InitializeWorkspace()
Target App
new WSID
Target Cluster
Create ChildWorkspace
c.sys.InitChildWorkspace() cdoc.sys.ChildWorkspace (owner) aproj.sys.InvokeCreateWorkspaceID()
Tagret App
Profile
Profile Cluster
c.sys.CreateWorkspaceID() cdoc.sys.WorkspaceID aproj.sys.InvokeCreateWorkspace()
Target App
(Target Cluster, CRC16(ownerWSID+"/"+wsName))
Target Cluster
c.sys.CreateWorkspace() cdoc.sys.WorkspaceDescriptor cdoc.$wsKind (air.Restaurant) aproj.sys.InitializeWorkspace()
Target App
new WSID
Target Cluster
c.sys.InitChildWorkspace()
AuthZ: Owner
PrincipalToken in header
PrincipalToken.ProfileWSID == Request.WSID
Params: wsName, wsKind, wsKindInitializationData, templateName, templateParams (JSON), wsClusterID
Check that wsName does not exist yet: View{pk: dummy, cc: wsName, value: idOfChildWorkspace}
409 conflict
Create CDoc {wsName, wsKind, wsKindInitializationData, templateName, templateParams, wsClusterID,
/* Updated aftewards by UpdateOwner*/
WSID, wsError}Trigger Projector<A, InvokeCreateWorkspaceID>
Trigger Projector
Subject:
Call WS[Subject.ProfileWSID].InitChildWorkspace()
wsName
wsKind
wsKindInitializationData // JSON
wsClusterID // Ideally user should be asked which cluster to use
Call WS[Subject.ProfileWSID].q.QueryChildWorkspaceByName() until (WSID || wsError)
Returns all fields of CDoc
aproj.sys.InvokeCreateWorkspaceID()
Triggered by CDoc
PseudoWSID = NewWSID(wsClusterID, CRC32(wsName))
// PseudoWSID is needed to avoid WSID generation bottlenecks
Call WS[$PseudoWSID].c.CreateWorkspaceID()
c.sys.CreateWorkspaceID()
AuthZ: System
SystemToken in header
Params: (
wsParams
) ownerWSID, ownerQName2, ownerID, wsName, wsKind, wsKindInitializationData, templateName, templateParams (JSON), wsClusterIDownerWSID
For profiles: PseudoWSID is calculated (from login) by client as NewWSID(1, ISO CRC32(login))
For subject workspaces: ProfileWSID
Check that ownerWSID + wsName does not exist yet: View to deduplication
pk: ownerWSID
cc: wsName
val: WSID
Get new WSID from View[NextBaseWSID]
Create WDoc[WorkspaceID]{wsParams, WSID: $NewWSID}
Triggers Projector[A, InvokeCreateWorkspace]
Triggers Projector[WorkspaceIDIdx]
aproj.sys.InvokeCreateWorkspace()
Triggered by WDoc
WS[new.WSID].c.CreateWorkspace()
c.sys.CreateWorkspace()
AuthZ: System
SystemToken in header
Params: wsParams, WSID
Check that CDoc<sys.WorkspaceDescriptor> does not exist yet (IRecords.GetSingleton())
return ok otherwise
if wsKindInitializationData is not valid
error = "Invalid workspaced descriptor data: ???"
Create CDoc<sys.WorkspaceDescriptor>{wsParams, WSID, createError: error, createdAtMs int64,
/* Updated aftewards */
initStartedAtMs int64, initError, initCompletedAtMs int64}Trigger Projector<A, InitializeWorkspace>
if not error
Create CDoc{wsKindInitializationData}
aproj.sys.InitializeWorkspace()
// error handling: just return
// Triggered by CDoc<sys.WorkspaceDescriptor>
If updated return // We do NOT react on update since we update record from projector
If len(new.createError) > 0
UpdateOwner(wsParams, new.WSID, new.createError)
return
// Must exist
wsDescr = GetSingleton(CDoc<sys.WorkspaceDescriptor>)
if wsDecr.initStartedAtMs == 0
WS[currentWS].c.sys.CUD(wsDescr.ID, initStartedAtMs)
err = workspace.buildWorkspace() // to init data
if err != nil: error = ("Workspace data initialization failed: v", err)
WS[currentWS].c.sys.CUD(wsDescr.ID, initError: error, initCompletedAtMs)
UpdateOwner(wsParams, new.WSID, error)
return
else if wsDecr.initCompletedAtMs == 0
error = "Workspace data initialization was interrupted"
WS[currentWS].c.sys.CUD(wsDescr.ID, initError: error, initCompletedAtMs)
UpdateOwner(wsParams, new.WSID, error)
return
else // initCompletedAtMs > 0
UpdateOwner(wsParams, new.WSID, wsDescr.initError)
return
UpdateOwner(wsParams, new.WSID, wsDescr.initError)
WS[wsParams.ownerWSID].c.sys.CUD(wsParams.ownerID, WSID, wsError)
Notes
Unable to work at AppWS because it is located in sys/registry app whereas we are logged in a target app. "token issued for another application" error will be result
Workspace initialized check is made in command processor only. Query processor just returns empty result because there is no data in non-inited workspace
c.sys.CreateWorkspace
orc.sys.CreateWorkspaceID
or (c.sys.CUD
+ System Principal) -> okcdoc.WorkspaceDescriptor
exists ->.initCompletedAtMs
> 0 && len(.initError
) == 0 -> okc.sys.CUD
-> will check afterparseCUDs
stage if we are updatingcdoc.WorkspaceDescriptor
orWDoc<BLOB>
nowthere is update only of (
cdoc.WorkspaceDescriptor
orWDoc<BLOB>
) only among CUDs -> ok
-> 403 forbidden +
workspace is not initialized
aproj.sys.InitializeWorkspace
:wsKind
==registry.AppWorkspace
-> self-initialized already, skip further workApp Workspace has
cdoc.WorkspaceDescriptor
only, there is nocdoc.$wsKind
cdoc.WorkspaceDescriptor
,cdoc.WorkspaceID
,c.sys.CeateWorkspace
,c.sys.CreateWorkspaceID
:ownerID
,ownerQName2
,ownerWSID
fields are made non-required becuase they are empty in App WorkspaceownerApp
field added to know in which app to update the owner
AppWorkspaces are initialized automatically after wiring the VVM before launch
for each app
PLog and WLog offsets are starting from
istructs.FirstOffset
for each App WS Number
AppWSID = (mainClusterID, wsNum + FirstBaseAppWSID)
cdoc.WorkspaceDescriptor
exists already at AppWSID -> skipgenerate new Sync Raw Event
add CUD create
cdoc.WorkspaceDescriptor
to the Eventput PLog
apply PLog event to records
put WLog
incr PLog and WLog offsets
//TODO AppWorkspaces must be created when application is deployed
App Workspaces amount is defined per app, default 10
See also
Originated from launchpad: Create Workspace v2, 21010
Last updated
Was this helpful?