private string[] GetPlayerUrls() { using (var scope = new ScopedDbContext <MusicDb>(serviceProvider)) { var urls = scope.Db.Devices.Where(x => !x.IsDisabled && x.Type != AudioDeviceType.Browser && !string.IsNullOrWhiteSpace(x.PlayerUrl)) .Select(x => x.PlayerUrl).Distinct(); return(urls.ToArray()); } }
/// <summary> /// Ctor /// </summary> /// <param name="purpose">Will this unit of work scope be used for reading or writing?</param> public UnitOfWorkScope(UnitOfWorkScopePurpose purpose) { this.purpose = purpose; if (scopedDbContext == null) { scopedDbContext = new ScopedDbContext(purpose == UnitOfWorkScopePurpose.Writing); isRoot = true; } if (purpose == UnitOfWorkScopePurpose.Writing && !scopedDbContext.ForWriting) { throw new InvalidOperationException( "Can't open a child UnitOfWorkScope for writing when the root scope " + "is opened for reading."); } }
private async Task AddDeviceToRuntime(Device device) { if (this.keepAlive != null) { using (var scope = new ScopedDbContext <MusicDb>(serviceProvider)) { DeviceRuntime dr = null; lock (this.devices) { //if (!this.devices.ContainsKey(device.KeyName)) if (GetDeviceRuntime(device.KeyName) == null) { dr = new DeviceRuntime { Key = device.KeyName, Type = device.Type, DisplayName = device.DisplayName, MaxSampleRate = device.MaxSampleRate, PlayerUrl = device.PlayerUrl, CommandSequenceNumber = 0, Status = new DeviceStatus { Key = device.KeyName, State = PlayerStates.Idle } }; dr.Playlist = device.Playlist.ToRuntime(scope.Db, dr); this.devices.Add(dr.Key, dr); log.Information($"{device.KeyName}, {device.DisplayName}, {device.Type}, url = {device.PlayerUrl } added to run time"); } else { log.Warning($"Device {device.DisplayName} already present in run time"); } } //LogDevices(); if (dr != null) { await PlayerReset(dr.Key); } } this.keepAlive.SetPlayerUrls(this.GetPlayerUrls()); } else { log.Warning($"not ready to add a device - keepAlive not yet started"); } }
private async Task PlayerDead(string url) { var affectedDevices = this.devices.Select(x => x.Value).Where(x => string.Compare(x.PlayerUrl, url, true) == 0); using (var scope = new ScopedDbContext <MusicDb>(serviceProvider)) { foreach (var dr in affectedDevices.ToArray()) { var device = await scope.Db.Devices.SingleAsync(x => x.KeyName == dr.Key); log.Information($"Device {device.DisplayName} to be removed from run time as polling has failed ... url was {url}"); RemoveDeviceFromRuntime(device); await SendDeviceDisabled(device); } } }
public async Task BrowserDisconnected(string browserKey) { using (var scope = new ScopedDbContext <MusicDb>(serviceProvider)) { var device = scope.Db.Devices.SingleOrDefault(x => x.KeyName == browserKey); if (device != null) { RemoveDeviceFromRuntime(device); await SendDeviceDisabled(device); } else { log.Warning($"audio for device {browserKey} not running"); } } }
public async Task AddPlaylistItem(string deviceKey, PlaylistItem pli) { using (var scope = new ScopedDbContext <MusicDb>(serviceProvider)) { var dr = GetDeviceRuntime(deviceKey); if (dr != null) { var item = pli.ToRuntime(scope.Db, dr); if (item != null) { dr.Playlist.Items.Add(pli.ToRuntime(scope.Db, dr)); var dto = new PlaylistUpdateDTO { DeviceKey = deviceKey, Items = dr.Playlist.Items.Select(x => x.ToDTO()) }; await SendPlaylist(dto); } } } }
/// <summary> /// Dispose implementation, checking post conditions for purpose and saving. /// </summary> /// <param name="disposing">Are we disposing?</param> protected override void Dispose(bool disposing) { if (disposing) { // We're disposing and SaveChanges wasn't called. That usually // means we're exiting the scope with an exception. Block saves // of the entire unit of work. if (purpose == UnitOfWorkScopePurpose.Writing && !saveChangesCalled) { scopedDbContext.BlockSave = true; // Don't throw here - it would mask original exception when exiting // a using block. } if (scopedDbContext != null && isRoot) { scopedDbContext.Dispose(); scopedDbContext = null; } } base.Dispose(disposing); }