public async Task StartAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); if (_watcher != null && _watcher.EnableRaisingEvents) { throw new InvalidOperationException("The listener has already been started."); } if (string.IsNullOrEmpty(_config.RootPath) || !Directory.Exists(_config.RootPath)) { throw new InvalidOperationException(string.Format("Path '{0}' is invalid. FilesConfiguration.RootPath must be set to a valid directory location.", _config.RootPath)); } CreateFileWatcher(); FileProcessorFactoryContext context = new FileProcessorFactoryContext(_config, _attribute, _triggerExecutor, _trace); _processor = _config.ProcessorFactory.CreateFileProcessor(context); ExecutionDataflowBlockOptions options = new ExecutionDataflowBlockOptions { BoundedCapacity = _processor.MaxQueueSize, MaxDegreeOfParallelism = _processor.MaxDegreeOfParallelism, }; _workQueue = new ActionBlock<FileSystemEventArgs>(async (e) => await ProcessWorkItem(e), options); // on startup, process any preexisting files that haven't been processed yet ProcessFiles(); // Create a timer to cleanup processed files. // The timer doesn't auto-reset. It will reset itself // when we receive more file events _cleanupTimer = new System.Timers.Timer() { AutoReset = false, Interval = _rand.Next(5 * 1000, 8 * 1000) }; _cleanupTimer.Elapsed += OnCleanupTimer; _cleanupTimer.Start(); await Task.FromResult<bool>(true); }
public FileProcessorTests() { rootPath = Path.GetTempPath(); combinedTestFilePath = Path.Combine(rootPath, attributeSubPath); Directory.CreateDirectory(combinedTestFilePath); DeleteTestFiles(combinedTestFilePath); config = new FilesConfiguration() { RootPath = rootPath }; FileTriggerAttribute attribute = new FileTriggerAttribute(attributeSubPath, "*.dat"); processor = CreateTestProcessor(attribute); JsonSerializerSettings settings = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.IsoDateFormat, }; _serializer = JsonSerializer.Create(settings); Environment.SetEnvironmentVariable("WEBSITE_INSTANCE_ID", InstanceId); }
public async Task ProcessFileAsync_ChangeTypeCreate_Success() { FileTriggerAttribute attribute = new FileTriggerAttribute(attributeSubPath, "*.dat"); processor = CreateTestProcessor(attribute); string testFile = WriteTestFile("dat"); FunctionResult result = new FunctionResult(true); mockExecutor.Setup(p => p.TryExecuteAsync(It.IsAny<TriggeredFunctionData>(), It.IsAny<CancellationToken>())).ReturnsAsync(result); string testFilePath = Path.GetDirectoryName(testFile); string testFileName = Path.GetFileName(testFile); FileSystemEventArgs eventArgs = new FileSystemEventArgs(WatcherChangeTypes.Created, testFilePath, testFileName); bool fileProcessedSuccessfully = await processor.ProcessFileAsync(eventArgs, CancellationToken.None); Assert.True(fileProcessedSuccessfully); string expectedStatusFile = processor.GetStatusFile(testFile); Assert.True(File.Exists(testFile)); Assert.True(File.Exists(expectedStatusFile)); string[] lines = File.ReadAllLines(expectedStatusFile); Assert.Equal(2, lines.Length); StatusFileEntry entry = (StatusFileEntry)_serializer.Deserialize(new StringReader(lines[0]), typeof(StatusFileEntry)); Assert.Equal(ProcessingState.Processing, entry.State); Assert.Equal(WatcherChangeTypes.Created, entry.ChangeType); Assert.Equal(InstanceId.Substring(0, 20), entry.InstanceId); entry = (StatusFileEntry)_serializer.Deserialize(new StringReader(lines[1]), typeof(StatusFileEntry)); Assert.Equal(ProcessingState.Processed, entry.State); Assert.Equal(WatcherChangeTypes.Created, entry.ChangeType); Assert.Equal(InstanceId.Substring(0, 20), entry.InstanceId); }