Create Workspace v2
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.CreateLoginusing 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.Loginstores login hash only
Create Login
- ⚠️ cdoc.sys.WorkspaceID is a large collection, must be wdoc.sys.WorkspaceID
| entity | app | ws | cluster |
|---|---|---|---|
| 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
| entity | app | ws | cluster |
|---|---|---|---|
| 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
- 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), wsClusterID- ownerWSID
- For profiles: PseudoWSID is calculated (from login) by client as NewWSID(1, ISO CRC32(login))
- For subject workspaces: ProfileWSID
- ownerWSID
- 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}
- Create CDoc
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.CreateWorkspaceorc.sys.CreateWorkspaceIDor (c.sys.CUD+ System Principal) -> okcdoc.WorkspaceDescriptorexists ->.initCompletedAtMs> 0 && len(.initError) == 0 -> okc.sys.CUD-> will check afterparseCUDsstage if we are updatingcdoc.WorkspaceDescriptororWDoc<BLOB>now- there is update only of (
cdoc.WorkspaceDescriptororWDoc<BLOB>) only among CUDs -> ok
- there is update only of (
- -> 403 forbidden +
workspace is not initialized
aproj.sys.InitializeWorkspace:wsKind==registry.AppWorkspace-> self-initialized already, skip further work- App Workspace has
cdoc.WorkspaceDescriptoronly, there is nocdoc.$wsKind cdoc.WorkspaceDescriptor,cdoc.WorkspaceID,c.sys.CeateWorkspace,c.sys.CreateWorkspaceID:ownerID,ownerQName2,ownerWSIDfields are made non-required becuase they are empty in App WorkspaceownerAppfield 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.WorkspaceDescriptorexists already at AppWSID -> skip- generate new Sync Raw Event
- add CUD create
cdoc.WorkspaceDescriptorto the Event - put PLog
- apply PLog event to records
- put WLog
- incr PLog and WLog offsets
- PLog and WLog offsets are starting from
- //TODO AppWorkspaces must be created when application is deployed
- for each app
- App Workspaces amount is defined per app, default 10
See also
- Originated from launchpad: Create Workspace v2, 21010