public static IDisposable ListenForBuildErrors(IObservable <Started> buildStarted, IObservable <BuildIssueDetected> issuesDetected, out IObservableList <BuildIssueDetected> issues) { var errors = new ListBehaviorSubject <BuildIssueDetected>(); issues = errors; return(Disposable.Combine( buildStarted.Select(b => BinaryMessage.TryParse(b.Command, BuildProject.MessageType, BuildProject.ReadDataFrom)) .NotNone() .Subscribe(_ => errors.OnClear()), buildStarted.Select(b => BinaryMessage.TryParse(b.Command, GenerateBytecode.MessageType, GenerateBytecode.ReadDataFrom)) .NotNone() .Subscribe(_ => errors.OnClear()), issuesDetected.Subscribe( issue => { errors.OnAdd(issue); }))); }
public static IDisposable Start( IObservable <IBinaryMessage> messages, IMessagingService daemon, AbsoluteFilePath projectPath, Guid projectId, BuildTarget target) { // TODO: do something with reset from the daemon // var reset = daemon.BroadcastedEvents<ResetPreviewEvent>(false); var daemonEvents = Observable.Merge <IEventData>( messages.TryParse(Started.MessageType, Started.ReadDataFrom).SelectSome(started => BinaryMessage.TryParse(started.Command, BuildProject.MessageType, BuildProject.ReadDataFrom).Select(build => new BuildStartedData { BuildId = build.Id, ProjectPath = projectPath.NativePath, BuildType = BuildTypeData.FullCompile, ProjectId = projectId, Target = target, }).Or( BinaryMessage.TryParse(started.Command, GenerateBytecode.MessageType, GenerateBytecode.ReadDataFrom).Select(reify => new BuildStartedData { BuildId = reify.Id, ProjectPath = projectPath.NativePath, BuildType = BuildTypeData.LoadMarkup, ProjectId = projectId, Target = target, }))), messages.TryParse(Ended.MessageType, Ended.ReadDataFrom).SelectSome(ended => BinaryMessage.TryParse(ended.Command, BuildProject.MessageType, BuildProject.ReadDataFrom).Select(build => new BuildEndedData { BuildId = build.Id, Status = ended.Success ? BuildStatus.Success : BuildStatus.Error, }).Or( BinaryMessage.TryParse(ended.Command, GenerateBytecode.MessageType, GenerateBytecode.ReadDataFrom).Select(reify => new BuildEndedData { BuildId = reify.Id, Status = ended.Success ? BuildStatus.Success : BuildStatus.Error, }))), messages .TryParse(BuildLogged.MessageType, BuildLogged.ReadDataFrom) .Select(e => new BuildLoggedData { BuildId = e.BuildId, Message = e.Text, }), messages .TryParse(BuildIssueDetected.MessageType, BuildIssueDetected.ReadDataFrom) .Select(e => new BuildIssueDetectedData { BuildId = e.BuildId, Path = e.Source.HasValue ? e.Source.Value.File : "", IssueType = e.Severity.ToPluginBuildEventType(), Message = e.Message.Replace("\r", "\0"), ErrorCode = e.Code, StartPosition = e.Source.TryGetStartPosition().OrDefault(), EndPosition = e.Source.TryGetEndPosition().OrDefault(), }), messages .TryParse(RegisterName.MessageType, RegisterName.ReadDataFrom) .Select(r => new RegisterClientEvent { DeviceId = r.DeviceId, DeviceName = r.DeviceName, ProjectId = projectId.ToString() }), messages .TryParse(DebugLog.MessageType, DebugLog.ReadDataFrom) .Select(l => new LogEvent { DeviceId = l.DeviceId, DeviceName = l.DeviceName, ProjectId = projectId.ToString(), ConsoleType = ConsoleType.DebugLog, Message = l.Message, Timestamp = DateTime.Now }), messages .TryParse(UnhandledException.MessageType, UnhandledException.ReadDataFrom) .Select(e => new ExceptionEvent { DeviceId = e.DeviceId, DeviceName = e.DeviceName, ProjectId = projectId.ToString(), Type = e.Type, Message = e.Message, StackTrace = e.StackTrace, Timestamp = DateTime.Now })); return(daemonEvents.Subscribe(daemon.Broadcast)); }
public ProjectPreview( IProjectLike project, IFileSystem shell, BuildOutputDirGenerator buildOutputDirGenerator, ProxyServer proxy) { Name = project.Name; var simulatorHost = ProjectProcess.SpawnAsync().Replay(1); var simulatorMessages = simulatorHost.Switch(p => p.Messages.RefCount()).Publish().RefCount(); var assemblyBuilt = simulatorMessages.TryParse(AssemblyBuilt.MessageType, AssemblyBuilt.ReadDataFrom); var bytecodeGenerated = simulatorMessages.TryParse(BytecodeGenerated.MessageType, BytecodeGenerated.ReadDataFrom); var bytecodeUpdated = simulatorMessages.TryParse(BytecodeUpdated.MessageType, BytecodeUpdated.ReadDataFrom); _project = project; _buildOutputDirGenerator = buildOutputDirGenerator; _proxy = proxy; _simulatorHost = simulatorHost; _assetsWatcher = new AssetsWatcher(shell, project.RootDirectory, Scheduler.Default); var bytecode = bytecodeGenerated.Select(msg => msg.Bytecode); _coalesceEntryCache = new CoalesceEntryCache(); var assets = project.BundleFiles.CombineLatest(project.FuseJsFiles, (a, b) => a.Concat(b)); var reifyMessages = ReifyProject(bytecode, bytecodeUpdated, _coalesceEntryCache, assets); var dependencyMessages = _assetsWatcher.UpdateChangedDependencies(bytecode.Select(bc => bc.Dependencies.ToImmutableHashSet())); var bundleFileMessages = _assetsWatcher.UpdateChangedBundleFiles(project.BundleFiles); var fuseJsFileMessages = _assetsWatcher.UpdateChangedFuseJsFiles(project.FuseJsFiles); _dispose = Observable.Merge( bundleFileMessages, dependencyMessages, fuseJsFileMessages, reifyMessages) .Subscribe(e => _coalesceEntryCache.Add(e)); var incommingMessages = new Subject <IBinaryMessage>(); var clientAdded = new Subject <string>(); var clientRemoved = new Subject <string>(); var socketServer = SocketServer.Start( port: 0, clientRun: (clientStream, endPoint) => { bool isDisconnected = false; var writeMessages = _coalesceEntryCache .ReplayFrom(-1) .ObserveOn(TaskPoolScheduler.Default) .Subscribe(cacheEntry => { if (isDisconnected) { return; } try { using (var memoryStream = new MemoryStream()) { using (var memoryStreamWriter = new BinaryWriter(memoryStream)) { // ReSharper disable once AccessToDisposedClosure cacheEntry.Entry.BlobData.Do(message => message.WriteTo(memoryStreamWriter)); clientStream.Write(memoryStream.ToArray(), 0, (int)memoryStream.Length); } } } catch (Exception) { isDisconnected = true; } }); var clientInfo = Optional.None <RegisterName>(); try { using (var binaryStream = new BinaryReader(clientStream)) { while (true) { var msg = BinaryMessage.ReadFrom(binaryStream); if (!clientInfo.HasValue) { clientInfo = BinaryMessage.TryParse(msg, RegisterName.MessageType, RegisterName.ReadDataFrom); if (clientInfo.HasValue) { clientAdded.OnNext(clientInfo.Value.DeviceId); } } incommingMessages.OnNext(msg); } } } finally { if (clientInfo.HasValue) { clientRemoved.OnNext(clientInfo.Value.DeviceId); } writeMessages.Dispose(); } }); Assembly = assemblyBuilt; Port = socketServer.LocalEndPoint.Port; Bytecode = bytecodeGenerated; PackageReferences = project.PackageReferences; ProjectReferences = project.ProjectReferences; ClientAdded = clientAdded; ClientRemoved = clientRemoved; Messages = Observable.Merge( incommingMessages, simulatorMessages); AccessCode = CodeGenerator.CreateRandomCode(5); }