public static Fake Create(IReadOnlyList <IEnumerable <ServerAction> > msgs, TimeSpan?ackDeadline = null, TimeSpan?ackExtendWindow = null, int?flowMaxElements = null, int?flowMaxBytes = null, int clientCount = 1, int threadCount = 1, TimeSpan?writeAsyncPreDelay = null, bool useMsgAsId = false) { var scheduler = new TestScheduler(threadCount: threadCount); TaskHelper taskHelper = scheduler.TaskHelper; List <DateTime> clientShutdowns = new List <DateTime>(); var msgEn = msgs.GetEnumerator(); var clients = Enumerable.Range(0, clientCount) .Select(_ => new FakeSubscriberServiceApiClient(msgEn, scheduler, scheduler.Clock, taskHelper, writeAsyncPreDelay ?? TimeSpan.Zero, useMsgAsId)) .ToList(); var settings = new SubscriberClient.Settings { Scheduler = scheduler, AckDeadline = ackDeadline, AckExtensionWindow = ackExtendWindow, FlowControlSettings = new FlowControlSettings(flowMaxElements, flowMaxBytes), }; Task Shutdown() { clientShutdowns.Locked(() => clientShutdowns.Add(scheduler.Clock.GetCurrentDateTimeUtc())); return(Task.FromResult(0)); } var subs = new SubscriberClientImpl(new SubscriptionName("projectid", "subscriptionid"), clients, settings, Shutdown, taskHelper); return(new Fake { Scheduler = scheduler, Time0 = scheduler.Clock.GetCurrentDateTimeUtc(), TaskHelper = taskHelper, Subscribers = clients, ClientShutdowns = clientShutdowns, Subscriber = subs, }); }
static int Main(string[] args) { if (args.Length != 3) { Console.WriteLine("Call with three args: <emulator port> <input file> <output file>"); Console.WriteLine("This connects to host 127.0.0.1, so requires the emulator to be started using ipv4, not ipv6:"); Console.WriteLine(" E.g. cloud-pubsub-emulator.bat --host=127.0.0.1 --port=8700"); Console.WriteLine("It reads and writes CSV files as specified in the 'Testing Ordering Keys' section of the"); Console.WriteLine(" 'Pub/Sub Ordering Key Client Libraries' doc."); Console.WriteLine(); return(1); } // Read inputs. var port = int.Parse(args[0]); var inputLines = File.ReadAllLines(args[1]).Select(line => new InputLine(line)).ToList(); // Setup gRPC channel to pubsub emulator. var channel = new Channel("127.0.0.1", port, ChannelCredentials.Insecure); // Create topic and subscription names. var topicName = new TopicName("project", $"topic-{Guid.NewGuid()}"); var subscriptionName = new SubscriptionName("project", $"subscription-{Guid.NewGuid()}"); // List that records all received messages. var recvMsgs = new List <PubsubMessage>(); // Run test. CreateTopicAndSubscription(); Task subTask = Subscribe(); IEnumerable <Task> pubTasks = Publish(); // Wait for publish and subscribe tasks to complete. Console.WriteLine("Waiting for all publish tasks to complete"); Task.WaitAll(pubTasks.ToArray()); Console.WriteLine("All publish tasks completed"); Console.WriteLine("Waiting for subscribe task to complete"); subTask.Wait(); Console.WriteLine("Subscribe task completed"); // Output ordered CSV file of recevied messages, for the validator. var csvLines = recvMsgs.Select(x => $"\"{x.OrderingKey}\",\"{x.Data.ToStringUtf8()}\"").ToList(); File.WriteAllLines(args[2], csvLines); Console.WriteLine("Output file written; all done :)"); return(0); void CreateTopicAndSubscription() { Console.WriteLine("Creating topic and subscription"); var pubApi = CreatePublisher(); var topic = pubApi.CreateTopic(topicName); var subApi = CreateSubscriber(); subApi.CreateSubscription(new Subscription { EnableMessageOrdering = true, TopicAsTopicName = topicName, SubscriptionName = subscriptionName, AckDeadlineSeconds = 120, }); } Task Subscribe() { Console.WriteLine("Creating subscribers"); var subs = new[] { CreateSubscriber(), CreateSubscriber(), CreateSubscriber() }; var sub = new SubscriberClientImpl(subscriptionName, subs, new SubscriberClient.Settings(), null); var recvCount = 0; var rnd = new Random(); Console.WriteLine("Starting subscriber callback"); return(sub.StartAsync(async(msg, ct) => { lock (recvMsgs) { recvMsgs.Add(msg.Clone()); recvCount += 1; if (recvCount == inputLines.Count) { Console.WriteLine("Received all messages, shutting down"); var dummyTask = sub.StopAsync(CancellationToken.None); } } if (rnd.Next(3) == 0) { await Task.Delay(rnd.Next(3)); } return SubscriberClient.Reply.Ack; })); } IEnumerable <Task> Publish() { Console.WriteLine("Creating publishers"); var pubs = new[] { CreatePublisher(), CreatePublisher(), CreatePublisher() }; var pub = new PublisherClientImpl(topicName, pubs, new PublisherClient.Settings { EnableMessageOrdering = true }, null); var publishTasks = new List <Task>(); Console.WriteLine("Starting to publish"); foreach (var inputLine in inputLines) { var pubTask = pub.PublishAsync(inputLine.OrderingKey, inputLine.Message); publishTasks.Add(pubTask); } Console.WriteLine("Publishing complete"); return(publishTasks); } PublisherServiceApiClient CreatePublisher() => new PublisherServiceApiClientBuilder { CallInvoker = channel.CreateCallInvoker() } .Build(); SubscriberServiceApiClient CreateSubscriber() => new SubscriberServiceApiClientBuilder { CallInvoker = channel.CreateCallInvoker() } .Build(); }