示例#1
0
 public Scope([NotNull] ILockObject lockObject, bool isDefault = false)
 {
     ScopeKey       = Interlocked.Increment(ref _currentScopeKey);
     _scopeHashCode = ScopeKey.GetHashCode();
     _lockObject    = lockObject ?? throw new ArgumentNullException(nameof(lockObject));
     _isDefault     = isDefault;
 }
        // API
        // API
        // API

        public async Task <ExchangeRateData> GetItemAsync()
        {
            ConfigData config = await ConfigDataProvider.GetConfigAsync();

            string jsFileName = GetJSFileName();

            using (ILockObject lockObject = await FileSystem.FileSystemProvider.LockResourceAsync(jsFileName)) {
                ExchangeRateData data = await DataProvider.GetAsync(KEY);

                if (data != null && data.SaveTime.Add(config.RefreshInterval) < DateTime.UtcNow)
                {
                    data = null;
                }
                if (data != null && !await FileSystem.FileSystemProvider.FileExistsAsync(jsFileName))
                {
                    data = null;
                }
                if (data == null)
                {
                    data = await GetExchangeRatesAsync();
                }
                await lockObject.UnlockAsync();

                return(data);
            }
        }
        /// <summary>
        /// Main
        /// </summary>
        public static async Task Main(string[] args)
        {
            // --> #1 AcquireLock with retry.
            using (ILockObject outerLockObject = _lockFactory.AcquireLock(_lockKey, TimeSpan.FromSeconds(3)))
                using (ILockObject innerLockObject = _lockFactory.AcquireLock(_lockKey, TimeSpan.FromSeconds(5), 2, TimeSpan.FromSeconds(2)))
                    Console.WriteLine($"Did I get a lock? -> {innerLockObject.IsAcquired}");

            // --> #2 AcquireLockAsync with retry.
            using (ILockObject outerLockObject = await _lockFactory.AcquireLockAsync(_lockKey, TimeSpan.FromSeconds(3)))
                using (ILockObject innerLockObject = await _lockFactory.AcquireLockAsync(_lockKey, TimeSpan.FromSeconds(5), 2, TimeSpan.FromSeconds(2)))
                    Console.WriteLine($"Did I get a lock? -> {innerLockObject.IsAcquired}");

            // --> #3 AcquireLockAsync with retry + timeout.
            try
            {
                using (CancellationTokenSource ctSource = new CancellationTokenSource(TimeSpan.FromSeconds(3.5)))
                {
                    using (ILockObject outerLockObject = await _lockFactory.AcquireLockAsync(_lockKey, TimeSpan.FromSeconds(3)))
                        using (ILockObject innerLockObject = await _lockFactory.AcquireLockAsync(_lockKey, TimeSpan.FromSeconds(5), 2, TimeSpan.FromSeconds(2), ctSource.Token))
                            Console.WriteLine($"Did I get a lock? -> {innerLockObject.IsAcquired}");
                }
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("I expected for an OperationCanceledException.");
            }

            // --> #4 Dinner is ready to eat.
            Parallel.For(0, 5, x => personEat(x));

            Console.WriteLine("End of the dinner.");
        }
        public async Task <bool> RemovePageDefinitionAsync(Guid pageGuid)
        {
            PageDefinition page;

            using (ILockObject lockObject = await LockDesignedPagesAsync()) {
                page = await LoadPageDefinitionAsync(pageGuid);

                if (page == null)
                {
                    return(false);
                }
                await Manager.StaticPageManager.RemovePageAsync(page.Url);

                await DataProvider.RemoveAsync(pageGuid);
                await RemoveCachedPageAsync(pageGuid);

                DesignedPagesDictionaryByUrl designedPagesUrl = await GetDesignedPagesWithoutLockAsync();
                await RemoveDesignedPageAsync(designedPagesUrl, page.Url);

                await lockObject.UnlockAsync();
            }
            await Auditing.AddAuditAsync($"{nameof(PageDefinitionDataProvider)}.{nameof(RemovePageDefinitionAsync)}", page.Url, page.PageGuid,
                                         "Remove Page",
                                         DataBefore : page,
                                         DataAfter : null,
                                         ExpensiveMultiInstance : true
                                         );

            return(true);
        }
        private async Task <PageDefinition> CreatePageDefinitionAsync(PageDefinition page)
        {
            using (ILockObject lockObject = await LockDesignedPagesAsync()) {
                PageDefinition.DesignedPage desPage = new PageDefinition.DesignedPage()
                {
                    PageGuid = page.PageGuid, Url = page.Url,
                };
                DesignedPagesDictionaryByUrl designedPagesByUrl = await GetDesignedPagesWithoutLockAsync();

                if (designedPagesByUrl.ContainsKey(desPage.Url.ToLower()))
                {
                    throw new Error(this.__ResStr("pageUrlErr", "A page with Url {0} already exists.", desPage.Url));
                }
                if (!await DataProvider.AddAsync(page))
                {
                    throw new Error(this.__ResStr("pageGuidErr", "A page with Guid {0} already exists.", desPage.PageGuid));
                }
                await SetCachedPageAsync(page);
                await AddDesignedPageAsync(designedPagesByUrl, page.Url.ToLower(), desPage);

                await lockObject.UnlockAsync();
            }
            await Auditing.AddAuditAsync($"{nameof(PageDefinitionDataProvider)}.{nameof(CreatePageDefinitionAsync)}", page.Url, page.PageGuid,
                                         "Create Page",
                                         DataBefore : null,
                                         DataAfter : page,
                                         ExpensiveMultiInstance : true
                                         );

            return(page);
        }
示例#6
0
        // SCHEDULER
        // SCHEDULER
        // SCHEDULER

        /// <summary>
        /// Run a scheduler item.
        /// </summary>
        /// <param name="name"></param>
        private async Task RunItemAsync(string name)
        {
            using (SchedulerDataProvider schedDP = new SchedulerDataProvider()) {
                using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync($"{AreaRegistration.CurrentPackage.AreaName}_RunItem_{name}")) {
                    SchedulerItemData evnt = await schedDP.GetItemAsync(name);

                    if (evnt == null)
                    {
                        throw new Error(this.__ResStr("errItemNotFound", "Scheduler item '{0}' does not exist."), name);
                    }
                    if (evnt.RunOnce)
                    {
                        evnt.Enabled = true;
                    }
                    if (!evnt.Enabled)
                    {
                        throw new Error(this.__ResStr("errItemDisabled", "Scheduler item '{0}' is currently disabled and cannot be scheduled."), evnt.Name);
                    }
                    evnt.Next   = DateTime.UtcNow.AddSeconds(-1);
                    evnt.Errors = null;
                    UpdateStatusEnum status = await schedDP.UpdateItemAsync(evnt);

                    await lockObject.UnlockAsync();

                    if (status != UpdateStatusEnum.OK)
                    {
                        throw new Error(this.__ResStr("errItemUpdFail", "Scheduler item '{0}' couldn't be updated."), evnt.Name);
                    }

                    Dispatch();// run the scheduler now
                }
            }
        }
示例#7
0
        public async Task <bool> AddItemsAsync(List <SearchData> list, string pageUrl, PageDefinition.PageSecurityType pageSecurity, string pageDescription, string pageSummary, DateTime pageCreated, DateTime?pageUpdated, DateTime searchStarted, string customData)
        {
            if (!IsUsable)
            {
                return(false);
            }
            bool status = false;

            using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync($"{AreaRegistration.CurrentPackage.AreaName}_{nameof(SearchDataProvider)}")) {
                if (pageUpdated != null && (DateTime)pageUpdated < pageCreated)
                {
                    pageCreated = (DateTime)pageUpdated;
                }
                using (SearchDataUrlDataProvider searchUrlDP = new SearchDataUrlDataProvider()) {
                    SearchDataUrl searchUrl = await searchUrlDP.GetItemByUrlAsync(pageUrl);

                    if (searchUrl == null)
                    {
                        searchUrl = new SearchDataUrl {
                            DatePageCreated = pageCreated,
                            DatePageUpdated = pageUpdated,
                            PageTitle       = pageDescription.Truncate(SearchDataUrl.MaxTitle),
                            PageUrl         = pageUrl,
                            PageSecurity    = pageSecurity,
                            PageSummary     = pageSummary.Truncate(SearchDataUrl.MaxSummary),
                            CustomData      = customData,
                        };
                        if (!await searchUrlDP.AddItemAsync(searchUrl))
                        {
                            throw new InternalError("Unexpected error adding SearchDataUrl for url {0}", pageUrl);
                        }
                    }
                    else
                    {
                        searchUrl.PageTitle       = pageDescription.Truncate(SearchDataUrl.MaxTitle);
                        searchUrl.PageSummary     = pageSummary.Truncate(SearchDataUrl.MaxSummary);
                        searchUrl.DatePageCreated = pageCreated;
                        searchUrl.DatePageUpdated = pageUpdated ?? pageCreated;
                        searchUrl.PageSecurity    = pageSecurity;
                        searchUrl.CustomData      = customData;
                        UpdateStatusEnum updStatus = await searchUrlDP.UpdateItemAsync(searchUrl);

                        if (updStatus != UpdateStatusEnum.OK)
                        {
                            throw new InternalError("Unexpected error updating SearchDataUrl for url {0} - {1}", pageUrl, updStatus);
                        }
                    }
                    foreach (SearchData data in list)
                    {
                        data.SearchDataUrlId = searchUrl.SearchDataUrlId;
                        data.DateAdded       = searchStarted;
                        await AddItemAsync(data);
                    }
                }
                status = true;
                await lockObject.UnlockAsync();
            }
            return(status);
        }
        public override async Task FlushAsync()
        {
            using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync(LogFile)) {
                await FlushAsyncNoLock();

                await lockObject.UnlockAsync();
            }
        }
示例#9
0
        private async Task MarkUpdatedAsync(int searchDataUrlId)
        {
            using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync($"{AreaRegistration.CurrentPackage.AreaName}_{nameof(SearchDataProvider)}")) {
                await DataProviderIOMode.MarkUpdatedAsync(searchDataUrlId);

                await lockObject.UnlockAsync();
            }
        }
 public void WriteToLogFile(string category, Logging.LevelEnum level, int relStack, string text)
 {
     YetaWFManager.Syncify(async() => {  // Logging is sync by definition (this is only used for startup logging)
         using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync(LogFile)) {
             await FileSystem.FileSystemProvider.AppendAllTextAsync(LogFile, text + "\r\n");
             await lockObject.UnlockAsync();
         }
     });
 }
示例#11
0
 public LockProcess(uint crc, ILockObject locker, UseResource res)
 {
     this._locker = locker;
     this._crc    = crc;
     Task.Run(() => Unlock());
     this._locker.Lock(this._crc);
     this._res = res;
     this._res.Increment();
 }
示例#12
0
        public async Task <ActionResult> RemoveAll()
        {
            using (SearchDataProvider searchDP = new SearchDataProvider()) {
                using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync($"{AreaRegistration.CurrentPackage.AreaName}_{nameof(SearchDataProvider)}")) {
                    await searchDP.RemoveItemsAsync(null);/* ALL */

                    await lockObject.UnlockAsync();
                }
                return(Reload(null, Reload: ReloadEnum.ModuleParts));
            }
        }
        private async Task <List <Guid> > GetDesignedGuidsAsync()
        {
            using (PageDefinitionDataProvider pageDP = new PageDefinitionDataProvider()) {
                using (ILockObject lockObject = await pageDP.LockDesignedPagesAsync()) {
                    List <Guid> pages = (from p in await pageDP.GetDesignedPagesWithoutLockAsync() select p.Value.PageGuid).ToList();
                    await lockObject.UnlockAsync();

                    return(pages);
                }
            }
        }
 private AspectOrientedMetadata(
     [NotNull] IDictionary <Type, Func <Attribute, Type> > typeSelectors,
     [NotNull] IDictionary <Type, Func <Attribute, IComparable> > orderSelectors,
     [NotNull] IDictionary <Type, Func <Attribute, object> > tagSelectors)
 {
     _lockObject         = new LockObject();
     _typeSelectors      = typeSelectors;
     _orderSelectors     = orderSelectors;
     _tagSelectors       = tagSelectors;
     _autowiringStrategy = default(IAutowiringStrategy);
 }
            public async Task InitAsync()
            {
                using (ILockObject lockObject = await FileSystem.FileSystemProvider.LockResourceAsync(LogFile)) {
                    if (await FileSystem.FileSystemProvider.FileExistsAsync(LogFile))
                    {
                        await FileSystem.FileSystemProvider.DeleteFileAsync(LogFile);
                    }
                    await FileSystem.FileSystemProvider.CreateDirectoryAsync(Path.GetDirectoryName(LogFile));

                    await lockObject.UnlockAsync();
                }
            }
示例#16
0
        public override async Task ClearAsync()
        {
            Package package = Package.GetPackageFromAssembly(GetType().Assembly);

            using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync(LogFile)) {
                try {
                    await FileSystem.FileSystemProvider.DeleteFileAsync(LogFile);
                } catch (Exception) { }
                await FileSystem.FileSystemProvider.CreateDirectoryAsync(Path.GetDirectoryName(LogFile));

                LogCache = new List <string>();
                await lockObject.UnlockAsync();
            }
        }
        public async Task <TResponse> ExecuteAsync <TResponse>(string key, Func <CancellationToken, Task <TResponse> > action)
        {
            ILockObject @lock = await _lockFactory.AcquireLockAsync(key);

            DateTime processStarted = DateTime.UtcNow;

            try
            {
                using var subscribedCancellationSource = new CancellationTokenSource();

                await _redisSubscriber.SubscribeAsync(
                    key,
                    (channel, _) =>
                {
                    _logger.LogInformation(
                        $"A cancellation message was received for key: {key}"
                        );

                    if (!subscribedCancellationSource.IsCancellationRequested)
                    {
                        subscribedCancellationSource.Cancel();
                    }
                }
                    ).ConfigureAwait(false);

                TResponse response = await Policy
                                     .Handle <Exception>()
                                     .WaitAndRetryAsync(_distributedCancellationConfiguration.MaxRetries, _ => _distributedCancellationConfiguration.MaximumRetryDelay)
                                     .ExecuteAsync(() =>
                {
                    return(action(subscribedCancellationSource.Token));
                });

                _logger.LogDebug($"Finished processing for key: {key}");

                await _databaseAsync.StringIncrementAsync(key);

                return(response);
            }
            catch (Exception ex)
            {
                throw new DistributedCancellationException("An exception happened", ex);
            }
            finally
            {
                await @lock.ReleaseAsync();

                await _redisSubscriber.UnsubscribeAsync(key).ConfigureAwait(false);
            }
        }
        public static async Task <RetrieveInitialInstallLogInfo> RetrieveInitialInstallLogAsync()
        {
            RetrieveInitialInstallLogInfo info = new RetrieveInitialInstallLogInfo();

            info.Ended = false;
            if (!SiteDefinition.INITIAL_INSTALL || SiteDefinition.INITIAL_INSTALL_ENDED)
            {
                info.Ended = true;
            }
            bool success = false;

            while (!success)
            {
                try {
                    // This is horrible, polling until the file is no longer in use.
                    // The problem is we can't use statics or some form of caching as this is called by multiple separate requests
                    // and the Package package itself is replaced while we're logging, so we just use a file to hold all data.
                    // unfortunately even the lockObject is lost when the Package package is replaced. Since this is only used
                    // during an initial install, it's not critical enough to make it perfect...
                    using (ILockObject lockObject = await FileSystem.FileSystemProvider.LockResourceAsync(LogFile)) {
                        if (await FileSystem.FileSystemProvider.FileExistsAsync(LogFile))
                        {
                            info.Lines = await FileSystem.FileSystemProvider.ReadAllLinesAsync(LogFile);

                            success = true;
                        }
                        await lockObject.UnlockAsync();
                    }
                } catch (Exception) {
                    if (YetaWFManager.IsSync())
                    {
                        Thread.Sleep(new TimeSpan(0, 0, 0, 0, 50));// wait a while - this is bad, only works because "other" instance has lock
                    }
                    else
                    {
                        await Task.Delay(new TimeSpan(0, 0, 0, 0, 50));// wait a while
                    }
                }
            }
            if (info.Lines.Count == 0)
            {
                return(info);
            }
            if (info.Lines.Last() == "+++DONE")
            {
                info.Ended = true;
            }
            return(info);
        }
示例#19
0
            public InstrumentSubscription(
                CQGCInstrumentResolver instrumentResolver,
                Instrument instrument,
                uint contractId)
            {
                this.instrumentResolver = instrumentResolver;
                Instrument = instrument;
                lockCookie = DeadlockMonitor.Cookie <InstrumentSubscription>("lockCookie-" + ContractId);
                ContractId = contractId;

                InstrumentParams = new InstrumentParams {
                    Instrument = instrument
                };
                InstrumentParams.VolaTranslatedByFeed = false;
                OrderBook = new OrderBook();
            }
示例#20
0
        public async Task RemoveOldItemsAsync(DateTime searchStarted)
        {
            if (!IsUsable)
            {
                return;
            }
            using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync($"{AreaRegistration.CurrentPackage.AreaName}_{nameof(SearchDataProvider)}")) {
                List <DataProviderFilterInfo> filters = null;
                filters = DataProviderFilterInfo.Join(filters, new DataProviderFilterInfo {
                    Field = nameof(SearchData.DateAdded), Operator = "<", Value = searchStarted
                });
                await RemoveItemsAsync(filters);
                await RemoveUnusedUrlsAsync();

                await lockObject.UnlockAsync();
            }
        }
        public async Task ReplaceItemAsync(MenuInfo data)
        {
            MenuInfo origMenu = Auditing.Active ? await GetItemAsync(data.ModuleGuid) : null;

            using (ILockObject lockObject = await YetaWF.Core.IO.Module.LockModuleAsync(data.ModuleGuid)) {
                await RemoveItemAsync(data.ModuleGuid);
                await AddItemAsync(data);

                await lockObject.UnlockAsync();
            }
            // audit code doesn't really work with this nested structure so skip for now
            //await Auditing.AddAuditAsync($"{nameof(MenuInfoDataProvider)}.{nameof(ReplaceItemAsync)}", "Menu", data.ModuleGuid,
            //    "Replace Menu",
            //    DataBefore: origMenu,
            //    DataAfter: data,
            //    ExpensiveMultiInstance: true
            //);
        }
示例#22
0
        private async Task <UpdateStatusEnum> UpdateItemAsync(string originalName, UserDefinition data)
        {
            if (string.Compare(originalName, SuperUserName, true) == 0)
            {
                if (data.UserName != originalName)
                {
                    throw new Error(this.__ResStr("cantRenameSuper", "The user \"{0}\" can't be renamed.", data.UserName));
                }
                // we allow status change even for a superuser (mainly to support login failures with automatic suspension)
                //if (data.UserStatus != UserStatusEnum.Approved)
                //    throw new Error(this.__ResStr("cantChangeStatusSuper", "The user \"{0}\" must remain an approved user. That's the only one that can bail you out when the entire site is broken.", data.UserName));
            }
            if (data.UserId != SuperuserDefinitionDataProvider.SuperUserId || string.Compare(data.UserName, SuperUserName, true) != 0)
            {
                throw new Error(this.__ResStr("cantUpdateSuper", "Wrong user id or user name - Can't update as superuser"));
            }
            UpdateStatusEnum result;
            UserDefinition   origSuperuser;// need to get current superuser because user may have changed the name through Appsettings.json

            Package package = YetaWF.Modules.Identity.Controllers.AreaRegistration.CurrentPackage;

            using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync($"{package.AreaName}.{nameof(SuperuserDefinitionDataProvider)}_{originalName}")) {
                List <DataProviderFilterInfo> filters = DataProviderFilterInfo.Join(null, new DataProviderFilterInfo {
                    Field = nameof(UserDefinition.UserId), Operator = "==", Value = SuperuserDefinitionDataProvider.SuperUserId
                });
                origSuperuser = await DataProvider.GetOneRecordAsync(filters);

                data.RolesList = new SerializableList <Role> {
                    new Role {
                        RoleId = Resource.ResourceAccess.GetSuperuserRoleId()
                    }
                };
                result = await DataProvider.UpdateAsync(origSuperuser.UserName, data.UserName, data);
            }
            await Auditing.AddAuditAsync($"{nameof(SuperuserDefinitionDataProvider)}.{nameof(UpdateItemAsync)}", data.UserName, Guid.Empty,
                                         "Update Superuser",
                                         DataBefore : origSuperuser,
                                         DataAfter : data
                                         );

            return(result);
        }
示例#23
0
        public override void SaveMessage(LogRecord record)
        {
            string text = string.Format("{0}-{1}-{2}-{3}-{4}-{5}-{6}({7})-{8}: {9},{10},{11},{12} - {13}:{14}",
                                        DateTime.Now /*Local Time*/, record.Category, record.SessionId, record.SiteIdentity, record.IPAddress, record.RequestedUrl, record.UserName, record.UserId, record.ReferrerUrl,
                                        record.ModuleName,
                                        record.Class,
                                        record.Method,
                                        record.Namespace,
                                        record.Level, record.Info);

            text = text.Replace("\n", "\r\n");

            YetaWFManager.Syncify(async() => {  // logging is sync by default
                using (ILockObject lockObject = await YetaWF.Core.IO.Caching.LockProvider.LockResourceAsync(LogFile)) {
                    LogCache.Add(text);
                    if (LogCache.Count >= MAXRECORDS)
                    {
                        await FlushAsyncNoLock();
                    }
                    await lockObject.UnlockAsync();
                }
            });
        }
示例#24
0
        internal Container([NotNull] string name, [NotNull] IContainer parent, [NotNull] ILockObject lockObject)
        {
            _lockObject          = lockObject ?? throw new ArgumentNullException(nameof(parent));
            _name                = $"{parent}/{name ?? throw new ArgumentNullException(nameof(name))}";
            _parent              = parent ?? throw new ArgumentNullException(nameof(parent));
            _eventSubject        = new Subject <ContainerEvent>(_lockObject);
            _registrationTracker = new RegistrationTracker(this);

            // Subscribe to events from the parent container
            RegisterResource(_parent.Subscribe(_eventSubject));

            // Creates a subscription to track infrastructure registrations
            RegisterResource(_eventSubject.Subscribe(_registrationTracker));

            // Register the current container in the parent container
            _parent.RegisterResource(this);

            // Notifies parent container about the child container creation
            (_parent as Container)?._eventSubject.OnNext(ContainerEvent.NewContainer(this));

            // Notifies about existing registrations in parent containers
            _eventSubject.OnNext(ContainerEvent.RegisterDependency(_parent, _parent.SelectMany(i => i)));
        }
        private static void personEat(int personId)
        {
            string person = $"Person({personId})";

            // Try to acquire a lock maximum 5 times.
            ILockObject lockObject = _waitAndRetryPolicy
                                     .Execute(
                ctx => _lockFactory.AcquireLock(_lockKey, TimeSpan.FromSeconds(5)),
                new Dictionary <string, object> {
                { "person", person }
            });

            if (lockObject.IsAcquired)
            {
                // We got a lock.
                Console.WriteLine($"{person} begin eat food.");

                Thread.Sleep(1000);

                // Try to release the lock.
                if (_random.NextDouble() < 0.8)
                {
                    lockObject.Release();

                    Console.WriteLine($"{person} released the lock.");
                }
                else
                {
                    Console.WriteLine($"{person} did not release lock.");
                }
            }
            else
            {
                Console.WriteLine($"{person} did not get food.");
            }
        }
示例#26
0
 public ScopeManager([NotNull] ILockObject lockObject, IContainer container) =>
示例#27
0
 // For tests only
 internal Scope([NotNull] ILockObject lockObject, long key)
 {
     ScopeKey       = key;
     _scopeHashCode = ScopeKey.GetHashCode();
     _lockObject    = lockObject ?? throw new ArgumentNullException(nameof(lockObject));
 }
示例#28
0
 public Subject([NotNull] ILockObject lockObject)
 {
     _lockObject = lockObject ?? throw new ArgumentNullException(nameof(lockObject));
 }
示例#29
0
 public RWLock()
 {
     _lock      = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
     _lockRead  = new ReaderLock(_lock);
     _lockWrite = new WriterLock(_lock);
 }
        public async Task SavePageDefinitionAsync(PageDefinition page)
        {
            if (page.Temporary)
            {
                throw new InternalError("Page {0} is a temporary page and can't be saved", page.PageGuid);
            }

            PageDefinition oldPage = null;

            using (ILockObject lockObject = await LockDesignedPagesAsync()) {
                page.Updated = DateTime.UtcNow;
                CleanupUsersAndRoles(page);
                await SaveImagesAsync(page.PageGuid, page);

                oldPage = await LoadPageDefinitionAsync(page.PageGuid);

                if (oldPage == null)
                {
                    throw new Error(this.__ResStr("pageDeleted", "Page '{0}' has been deleted and can no longer be updated."), page.Url);
                }

                Guid newPage = await FindPageAsync(page.Url);

                if (newPage != Guid.Empty && newPage != page.PageGuid)
                {
                    throw new Error(this.__ResStr("pageRename", "A page with Url '{0}' already exists."), page.Url);
                }

                UpdateStatusEnum status = await DataProvider.UpdateAsync(page.PageGuid, page.PageGuid, page);

                switch (status)
                {
                case UpdateStatusEnum.OK:
                    break;

                case UpdateStatusEnum.NewKeyExists:
                    throw new InternalError("Unexpected UpdateStatusEnum.NewKeyExists in SavePageDefinition");

                case UpdateStatusEnum.RecordDeleted:
                    throw new InternalError("Unexpected UpdateStatusEnum.RecordDeleted in SavePageDefinition");
                }
                await SetCachedPageAsync(page);

                await Manager.StaticPageManager.RemovePageAsync(page.Url);

                if (newPage == Guid.Empty)
                {
                    DesignedPagesDictionaryByUrl designedPagesByUrl = await GetDesignedPagesWithoutLockAsync();

                    designedPagesByUrl.Remove(oldPage.Url.ToLower());

                    PageDefinition.DesignedPage desPage = new PageDefinition.DesignedPage()
                    {
                        PageGuid = page.PageGuid, Url = page.Url,
                    };
                    await AddDesignedPageAsync(designedPagesByUrl, page.Url.ToLower(), desPage);
                }
                await lockObject.UnlockAsync();
            }
            await Auditing.AddAuditAsync($"{nameof(PageDefinitionDataProvider)}.{nameof(SavePageDefinitionAsync)}", oldPage.Url, oldPage.PageGuid,
                                         "Save Page",
                                         DataBefore : oldPage,
                                         DataAfter : page,
                                         ExpensiveMultiInstance : true
                                         );
        }