public async Task <bool> RemoveItemByIdentityAsync(int id) { VoiceMailData origData = Auditing.Active ? await GetItemByIdentityAsync(id) : null; if (!await DataProvider.RemoveByIdentityAsync(id)) { return(false); } await SetupClient(); try { if (YetaWFManager.IsSync()) { RecordingResource.Delete(pathSid: origData.RecordingSid); } else { await RecordingResource.DeleteAsync(pathSid : origData.RecordingSid); } } catch (Exception) { } await Auditing.AddAuditAsync($"{nameof(VoiceMailDataProvider)}.{nameof(RemoveItemByIdentityAsync)}", Dataset, Guid.Empty, $"Remove Voice Mail Entry {id}", DataBefore : origData, DataAfter : null ); return(true); }
/// <summary> /// Called when the first node of a multi-instance site is starting up. /// </summary> public async Task InitializeFirstNodeStartupAsync() { if (YetaWF.Modules.Caching.Startup.Application.LockProvider != YetaWF.Modules.Caching.Startup.Application.RedisCacheProvider) { return; } // this is the first node, so clear all data IDatabase db = Redis.GetDatabase(); string keyPrefix = WebConfigHelper.GetValue(YetaWF.Modules.Caching.Controllers.AreaRegistration.CurrentPackage.AreaName, "RedisKeyPrefix", Application.DefaultRedisKeyPrefix); System.Net.EndPoint endPoint = Redis.GetEndPoints().First(); RedisKey[] keys = Redis.GetServer(endPoint).Keys(pattern: $"{keyPrefix}*").ToArray(); //await db.ExecuteAsync("FLUSHALL"); foreach (RedisKey key in keys) { if (!key.ToString().EndsWith(YetaWF.Core.Support.Startup.FirstNodeIndicator)) // don't remove the current first-time startup lock { if (YetaWFManager.IsSync()) { db.KeyDelete(key); } else { await db.KeyDeleteAsync(key); } } } }
private async Task <string> GetJSONResponseAsync(string url) { var http = (HttpWebRequest)WebRequest.Create(new Uri(url)); http.Accept = "application/json"; http.ContentType = "application/json"; http.Method = "POST"; System.Net.WebResponse resp; try { if (YetaWFManager.IsSync()) { resp = http.GetResponse(); } else { resp = await http.GetResponseAsync(); } } catch (Exception exc) { throw new InternalError("An error occurred retrieving exchange rates from openexchangerates.org - {0}", ErrorHandling.FormatExceptionMessage(exc)); } using (System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream())) { if (YetaWFManager.IsSync()) { return(sr.ReadToEnd().Trim()); } else { return((await sr.ReadToEndAsync()).Trim()); } } }
public async Task UnlockAsync() { for (; Locked;) { if (YetaWFManager.IsSync()) { if (localLock.Wait(10)) { LocalLocked = true; } } else { await localLock.WaitAsync(); LocalLocked = true; } if (LocalLocked) { LockKeys.Remove(Key); localLock.Release(); LocalLocked = false; Locked = false; break; } if (YetaWFManager.IsSync()) { Thread.Sleep(new TimeSpan(0, 0, 0, 0, 25));// wait a while - this is bad, only works because "other" instance has lock } else { await Task.Delay(new TimeSpan(0, 0, 0, 0, 25));// wait a while } } }
public virtual async Task CreateDirectoryAsync(string targetFolder) { VerifyAccess(targetFolder); if (Directory.Exists(targetFolder)) { return; // avoid exception spam } int retry = 10; // folder occasionally are in use so we'll just wait a bit while (retry > 0) { try { Directory.CreateDirectory(targetFolder); return; } catch (Exception) { if (retry <= 1) { throw; } } 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 } --retry; } }
internal async Task LockAsync() { if (Locked) { throw new InternalError($"{nameof(LockAsync)} called while already holding a lock on {Key}"); } for ( ; !Locked;) { if (YetaWFManager.IsSync()) { if (localLock.Wait(10)) { LocalLocked = true; } } else { await localLock.WaitAsync(); LocalLocked = true; } if (LocalLocked) { if (YetaWFManager.IsSync()) { if (Db.LockTake(Key, Id.ToString(), new TimeSpan(0, 10, 0))) { Locked = true; } } else { if (await Db.LockTakeAsync(Key, Id.ToString(), new TimeSpan(0, 10, 0))) { Locked = true; } } localLock.Release(); LocalLocked = false; if (Locked) { break; } } if (YetaWFManager.IsSync()) { Thread.Sleep(new TimeSpan(0, 0, 0, 0, 25));// wait a while - this is bad, only works because "other" instance has lock } else { await Task.Delay(new TimeSpan(0, 0, 0, 0, 25));// wait a while } } }
public Task <int> ReadAsync(byte[] btes, int offset, int length) { if (YetaWFManager.IsSync()) { return(Task.FromResult(Stream.Read(btes, offset, length))); } else { return(Stream.ReadAsync(btes, offset, length)); } }
public Task WriteAsync(byte[] btes, int offset, int length) { if (YetaWFManager.IsSync()) { Stream.Write(btes, offset, length); return(Task.CompletedTask); } else { return(Stream.ReadAsync(btes, offset, length)); } }
// Files public override async Task <List <string> > ReadAllLinesAsync(string filePath) { VerifyAccess(filePath); if (YetaWFManager.IsSync()) { return(File.ReadLines(filePath).ToList()); } else { return((await File.ReadAllLinesAsync(filePath)).ToList()); } }
public Task CopyToAsync(MemoryStream memStream) { if (YetaWFManager.IsSync()) { Stream.CopyTo(memStream); return(Task.CompletedTask); } else { return(Stream.CopyToAsync(memStream)); } }
public Task FlushAsync() { if (YetaWFManager.IsSync()) { Stream.Flush(); return(Task.CompletedTask); } else { return(Stream.FlushAsync()); } }
public override Task AppendAllTextAsync(string filePath, string text) { VerifyAccess(filePath); if (YetaWFManager.IsSync()) { File.AppendAllText(filePath, text); return(Task.CompletedTask); } else { return(File.AppendAllTextAsync(filePath, text)); } }
public override Task <string> ReadAllTextAsync(string filePath) { VerifyAccess(filePath); if (YetaWFManager.IsSync()) { string text = File.ReadAllText(filePath); return(Task.FromResult(text)); } else { return(File.ReadAllTextAsync(filePath)); } }
public override Task WriteAllBytesAsync(string filePath, byte[] data) { VerifyAccess(filePath); if (YetaWFManager.IsSync()) { File.WriteAllBytes(filePath, data); return(Task.CompletedTask); } else { return(File.WriteAllBytesAsync(filePath, data)); } }
public override Task <byte[]> ReadAllBytesAsync(string filePath) { VerifyAccess(filePath); if (YetaWFManager.IsSync()) { byte[] data = File.ReadAllBytes(filePath); return(Task.FromResult(data)); } else { return(File.ReadAllBytesAsync(filePath)); } }
/// <summary> /// Publish a message to a channel. /// </summary> /// <param name="channel">The channel name.</param> /// <param name="message">The message object.</param> public async Task PublishAsync(string channel, object message) { ISubscriber subscriber = Redis.GetSubscriber(); if (YetaWFManager.IsSync()) { subscriber.Publish($"{KeyPrefix}{channel}", Utility.JsonSerialize(message)); } else { await subscriber.PublishAsync($"{KeyPrefix}{channel}", Utility.JsonSerialize(message)); } }
public override Task AppendAllLinesAsync(string filePath, List <string> lines) { VerifyAccess(filePath); if (YetaWFManager.IsSync()) { File.AppendAllLines(filePath, lines); return(Task.CompletedTask); } else { return(File.AppendAllLinesAsync(filePath, lines)); } }
/// <summary> /// Unsubscribe from a channel. /// </summary> /// <param name="channel">The channel name.</param> public async Task UnsubscribeAsync(string channel) { ISubscriber subscriber = Redis.GetSubscriber(); if (YetaWFManager.IsSync()) { subscriber.Unsubscribe($"{KeyPrefix}{channel}"); } else { await subscriber.UnsubscribeAsync($"{KeyPrefix}{channel}"); } }
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); }
public async Task UnlockAsync() { if (Locked) { if (YetaWFManager.IsSync()) { Db.LockRelease(Key, Id.ToString()); } else { await Db.LockReleaseAsync(Key, Id.ToString()); } Locked = false; } }
// API /// <summary> /// Subscribe to a channel. /// </summary> /// <param name="channel">The channel name.</param> /// <param name="callback">The callback invoked when a message is published to the channel.</param> public async Task SubscribeAsync(string channel, Func <string, object, Task> callback) { ISubscriber subscriber = Redis.GetSubscriber(); if (YetaWFManager.IsSync()) { subscriber.Subscribe($"{KeyPrefix}{channel}", (ch, msg) => { callback(channel, Utility.JsonDeserialize(msg.ToString())).Wait(); }); } else { await subscriber.SubscribeAsync($"{KeyPrefix}{channel}", async (ch, msg) => { await callback(channel, Utility.JsonDeserialize(msg.ToString())); }); } }
// API /// <summary> /// Add a shared object. /// </summary> /// <remarks>This requires an active Lock using a lock provider.</remarks> public async Task AddAsync <TYPE>(string key, TYPE data) { key = KeyPrefix + key; key = GetKey(key); // save new version shared and locally byte[] cacheData = new GeneralFormatter().Serialize(data); DateTime created = DateTime.UtcNow; IDatabase db = Redis.GetDatabase(); if (YetaWFManager.IsSync()) { db.KeyDelete(GetVersionKey(key)); db.KeyDelete(GetDataKey(key)); db.StringSet(GetVersionKey(key), created.Ticks); db.StringSet(GetDataKey(key), cacheData); } else { await db.KeyDeleteAsync(GetVersionKey(key)); await db.KeyDeleteAsync(GetDataKey(key)); await db.StringSetAsync(GetVersionKey(key), created.Ticks); await db.StringSetAsync(GetDataKey(key), cacheData); } StaticCacheObject cachedObj = new StaticCacheObject { Key = key, Value = data, Created = created, }; lock (_lockObject) { // used to protect StaticObjects - local only StaticObjects.Remove(key); StaticObjects.Add(key, cachedObj); } }
// API public async Task AddAsync <TYPE>(string key, TYPE data) { key = KeyPrefix + key; // save new version shared and locally byte[] cacheData = new GeneralFormatter().Serialize(data); DateTime created = DateTime.UtcNow; IDatabase db = Redis.GetDatabase(); if (YetaWFManager.IsSync()) { db.KeyDelete(GetVersionKey(key)); db.KeyDelete(GetDataKey(key)); db.StringSet(GetVersionKey(key), created.Ticks); db.StringSet(GetDataKey(key), cacheData); } else { await db.KeyDeleteAsync(GetVersionKey(key)); await db.KeyDeleteAsync(GetDataKey(key)); await db.StringSetAsync(GetVersionKey(key), created.Ticks); await db.StringSetAsync(GetDataKey(key), cacheData); } LocalSharedCacheObject localCacheObj = new LocalSharedCacheObject { Created = created, Key = key, Value = cacheData, }; using (ICacheDataProvider localCacheDP = YetaWF.Core.IO.Caching.GetLocalCacheProvider()) { await localCacheDP.AddAsync(key, localCacheObj); // save locally cached version } }
public async Task <GetObjectInfo <TYPE> > GetAsync <TYPE>(string key) { key = KeyPrefix + key; // get locally cached version GetObjectInfo <LocalSharedCacheObject> localInfo; using (ICacheDataProvider localCacheDP = YetaWF.Core.IO.Caching.GetLocalCacheProvider()) { localInfo = await localCacheDP.GetAsync <LocalSharedCacheObject>(key); if (!localInfo.Success) { // no locally cached data localInfo = new GetObjectInfo <LocalSharedCacheObject> { Data = new LocalSharedCacheObject { Created = DateTime.MinValue, Key = key, Value = null, }, Success = false, }; } // get shared cached version IDatabase db = Redis.GetDatabase(); long? val; if (YetaWFManager.IsSync()) { val = (long?)db.StringGet(GetVersionKey(key)); } else { val = (long?)await db.StringGetAsync(GetVersionKey(key)); } if (val != null) { DateTime sharedCacheCreated = new DateTime((long)val); if (sharedCacheCreated != localInfo.Data.Created) { // shared cached version is different, retrieve and save locally byte[] sharedCacheData; if (YetaWFManager.IsSync()) { sharedCacheData = db.StringGet(GetDataKey(key)); } else { sharedCacheData = await db.StringGetAsync(GetDataKey(key)); } if (sharedCacheData == null) // this shouldn't happen, we just got the shared version // return the local data instead { } else { LocalSharedCacheObject localCacheObj = new LocalSharedCacheObject { Created = sharedCacheCreated, Key = key, Value = sharedCacheData, }; await localCacheDP.AddAsync(key, localCacheObj); // save as locally cached version return(new GetObjectInfo <TYPE> { Success = true, Data = new GeneralFormatter().Deserialize <TYPE>(sharedCacheData), }); } } else { // shared version same as local version } } else { // there is no shared version } // return the local data if (localInfo.Success) { return(new GetObjectInfo <TYPE> { Success = true, Data = new GeneralFormatter().Deserialize <TYPE>(localInfo.Data.Value), }); } else { return(new GetObjectInfo <TYPE> { Success = false, }); } } }
internal async Task LockAsync() { if (Locked) { throw new InternalError($"{nameof(LockAsync)} called while already holding a lock on {Key}"); } for ( ; !Locked;) { if (YetaWFManager.IsSync()) { if (localLock.Wait(10)) { LocalLocked = true; } } else { await localLock.WaitAsync(); LocalLocked = true; } if (LocalLocked) { try { FileStream = new System.IO.FileStream(LockFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None); if (YetaWFManager.IsSync()) { FileStream.Write(new byte[] { 99 }, 0, 1); } else { await FileStream.WriteAsync(new byte[] { 99 }, 0, 1); } Locked = true; } catch (Exception) { } finally { if (!Locked) { if (FileStream != null) { FileStream.Close(); FileStream = null; } } } localLock.Release(); LocalLocked = false; if (Locked) { break; } } if (YetaWFManager.IsSync()) { Thread.Sleep(new TimeSpan(0, 0, 0, 0, 25));// wait a while - this is bad, only works because "other" instance has lock } else { await Task.Delay(new TimeSpan(0, 0, 0, 0, 25));// wait a while } } }
public async Task <GetObjectInfo <TYPE> > GetAsync <TYPE>(string key) { key = KeyPrefix + key; key = GetKey(key); // get cached version TYPE data = default(TYPE); StaticCacheObject cachedObj; bool localValid; lock (_lockObject) { // used to protect StaticObjects - local only localValid = StaticObjects.TryGetValue(key, out cachedObj); } if (!localValid) { cachedObj = new StaticCacheObject { Key = key, Value = data, Created = DateTime.MinValue, }; } else { data = (TYPE)cachedObj.Value; } // get shared cached version IDatabase db = Redis.GetDatabase(); long? val; if (YetaWFManager.IsSync()) { val = (long?)db.StringGet(GetVersionKey(key)); } else { val = (long?)await db.StringGetAsync(GetVersionKey(key)); } if (val != null) { DateTime sharedCacheCreated = new DateTime((long)val); if (sharedCacheCreated != cachedObj.Created) { // shared cached version is different, retrieve and save locally byte[] sharedCacheData; if (YetaWFManager.IsSync()) { sharedCacheData = db.StringGet(GetDataKey(key)); } else { sharedCacheData = await db.StringGetAsync(GetDataKey(key)); } if (sharedCacheData == null) { data = default(TYPE); } else { data = new GeneralFormatter().Deserialize <TYPE>(sharedCacheData); } cachedObj = new StaticCacheObject { Created = sharedCacheCreated, Key = key, Value = data, }; localValid = true; lock (_lockObject) { // used to protect StaticObjects - local only StaticObjects.Remove(key); StaticObjects.Add(key, cachedObj); } } else { // shared version same as local version } return(new GetObjectInfo <TYPE> { Success = true, Data = data, }); } else { // no shared cache if (!localValid) { return(new GetObjectInfo <TYPE> { Success = false }); } else { return(new GetObjectInfo <TYPE> { Success = true, Data = data, }); } } }