Пример #1
0
        /// <summary>
        /// Host app must call this when receiving http request on POST /api/retro/main
        /// </summary>
        public async Task <MainResponse> HandleHttpMain(MainRequest req)
        {
            var resp = new MainResponse();

            try
            {
                var user = ClientPlex.GetUser(req.SessionKey);
                if (user == null)
                {
                    return new MainResponse {
                               ErrorCode = Constants.ERRCODE_BADUSER
                    }
                }
                ;
                await HandleHttpMain(req, user, resp);
            }
            catch (Exception ex)
            {
                resp.ErrorCode = Constants.ERRCODE_INTERNAL;
                Diagnostics.ReportClientCallError?.Invoke(ex.ToString());
            }
            return(resp);
        }
Пример #2
0
        private async Task HandleHttpMain(MainRequest req, IUser user, MainResponse resp)
        {
            //initialize
            if (req.Initialze != null)
            {
                resp.DataDictionary = Retrovert.DataDictionaryToWire(DataDictionary, user, LanguageMessages);
            }

            //load datons
            if (req.GetDatons != null)
            {
                var getResponses = new List <GetDatonResponse>();
                foreach (var drequest in req.GetDatons)
                {
                    var loadResult = await GetDaton(DatonKey.Parse(drequest.Key), user, forceCheckLatest : drequest.ForceLoad);

                    var getResponse = new GetDatonResponse
                    {
                        Errors = loadResult.Errors
                    };
                    if (loadResult.Daton != null)                                                                                      //null means it was not found by key, usually
                    {
                        bool doReturnToCaller = loadResult.Daton.Version == null || drequest.KnownVersion != loadResult.Daton.Version; //omit if client already has the current version
                        if (doReturnToCaller)
                        {
                            getResponse.CondensedDaton = new CondensedDatonResponse
                            {
                                CondensedDatonJson = Retrovert.ToWire(DataDictionary, loadResult.Daton, false)
                            };
                        }
                        if (drequest.DoSubscribe && loadResult.Daton is Persiston)
                        {
                            ClientPlex.ManageSubscribe(req.SessionKey, loadResult.Daton.Key, loadResult.Daton.Version, true);
                        }
                    }
                    else
                    {
                        getResponse.Key = drequest.Key; //only needed if daton is not returned to client
                    }
                    getResponses.Add(getResponse);
                }
                resp.GetDatons = getResponses.ToArray();
            }

            //save datons
            if (req.SaveDatons != null)
            {
                var diffs = new List <PersistonDiff>();
                foreach (var saveRequest in req.SaveDatons)
                {
                    var diff = Retrovert.FromDiff(DataDictionary, saveRequest);
                    diffs.Add(diff);
                }
                (bool success, var results) = await SaveDatons(req.SessionKey, user, diffs.ToArray());

                var saveResponses = new List <SavePersistonResponse>();
                foreach (var result in results)
                {
                    saveResponses.Add(new SavePersistonResponse
                    {
                        IsDeleted = result.IsDeleted,
                        IsSuccess = result.IsSuccess,
                        OldKey    = result.OldKey.ToString(),
                        NewKey    = result.NewKey?.ToString(),
                        Errors    = result.Errors
                    });
                }
                resp.SavedPersistons       = saveResponses.ToArray();
                resp.SavePersistonsSuccess = success;
            }

            //change datons state
            if (req.ManageDatons != null)
            {
                var manageResponses = new List <ManageDatonResponse>(req.ManageDatons.Length);
                foreach (var mrequest in req.ManageDatons)
                {
                    //what does the caller wants to change?
                    var  datonKey       = DatonKey.Parse(mrequest.Key);
                    bool wantsLock      = mrequest.SubscribeState == 2;
                    bool wantsSubscribe = mrequest.SubscribeState >= 1;

                    //handle change in subscription
                    //(Performance note: unsubscribe should happen before unlock so that the unlock-propogation can short circuit reloading. Ultimately
                    //if only one client is dealing with a daton and that client releases the lock and subscription, this server can forget about it
                    //immediately.)
                    bool isSubscribed = false;
                    if (datonKey is PersistonKey)
                    {
                        ClientPlex.ManageSubscribe(req.SessionKey, datonKey, mrequest.Version, wantsSubscribe);
                        isSubscribed = wantsSubscribe;
                    }

                    //handle change in lock
                    string lockErrorCode = "";
                    bool   hasLock       = false;
                    if (wantsLock)
                    {
                        if (string.IsNullOrEmpty(mrequest.Version))
                        {
                            throw new Exception("Version required to lock daton");
                        }
                        (hasLock, lockErrorCode) = LockManager.RequestLock(datonKey, mrequest.Version, req.SessionKey);
                    }
                    else
                    {
                        LockManager.ReleaseLock(datonKey, req.SessionKey);
                    }

                    manageResponses.Add(new ManageDatonResponse
                    {
                        ErrorCode      = lockErrorCode,
                        Key            = mrequest.Key,
                        SubscribeState = hasLock ? 2 : (isSubscribed ? 1 : 0)
                    });
                }
                resp.ManageDatons = manageResponses.ToArray();
            }

            //quit - free up locks and memory
            if (req.DoQuit)
            {
                ClientPlex.DeleteSession(req.SessionKey);
                LockManager.ReleaseLocksForSession(req.SessionKey);
            }
        }