public async Task Run( [ServiceBusTrigger("%ServiceBusQueueName%", Connection = "ServiceBusConnectionString")] SyncMessage message, [ServiceBus("%ServiceBusNormalCompetitionsQueueName%", EntityType.Topic, Connection = "ServiceBusConnectionString")] IAsyncCollector <Message> output) { var source = factory.GetSource(message.ConnectorType); var retriever = source.GetRetriever(message); var competitions = await retriever.GetAllAsync(); var tasks = competitions .Select(x => new CompetitionMessage { Name = x.Name, Place = x.Place, SportType = x.SportType, StartDate = x.StartDate, Teams = x.Teams.Select(m => new TeamMessage { Name = m.Name }).ToList(), UniqueId = x.UniqueId, LiveUri = x.LiveUri }) .Select(competition => output.AddAsync(competition.ToBrokeredMessage(competition.UniqueId.ToString()))) .ToList(); await Task.WhenAll(tasks); }
public async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context) { //todo: when message is received, the function can be scheduled till time T, //e.g. till 3-5 minutes prior to match start, after that it can change it's polling behavior from // 60 days (e.g. time from the match info is parsed) - simply it waits, without being billed till the moment // to 3 every 2 secs while the match is finished and exits. //Multiple sources can be queried from this 1 function, for instance if we've specified them in a message, that scheduled the function. var message = context.GetInput <LiveSyncMessage>(); int pollingInterval = message.PollingIntervalInSec; DateTime expiryTime = message.FinishTime; if (message.StartTime >= context.CurrentUtcDateTime.AddMinutes(1)) { //Orchestration was scheduled, and waits till the start of a match, without billing. var sleepUntil = message.StartTime - context.CurrentUtcDateTime; var nextCheck = context.CurrentUtcDateTime.AddSeconds(sleepUntil.TotalSeconds); await context.CreateTimer(nextCheck, CancellationToken.None); } while (DateTime.UtcNow < expiryTime) { //todo: if match has ended or was cancelled - skip. var source = factory.GetSource(message.ConnectorType); var retriever = source.GetRetriever(message); //todo: currently only all is supported for the demo //todo: can support almost unlimited amount of calls to source apis, that can be aggregated in this point. DurableHttpResponse response = await context.CallHttpAsync(System.Net.Http.HttpMethod.Get, message.Uri); var stats = await retriever.GetLiveAsync(response.Content); var result = new CompetitionStatsMessage { CompetitionId = message.CompetitionUniqueId, Score = stats.Score }; if (!String.IsNullOrEmpty(result.CompetitionId)) { await context.CallActivityAsync("LiveDataFunctionResultServiceBus", result); // Orchestration sleeps until this time. var nextCheck = context.CurrentUtcDateTime.AddSeconds(pollingInterval); await context.CreateTimer(nextCheck, CancellationToken.None); } } }