From d55c9ccba51b526ded8ff23d19627c44238e1e2d Mon Sep 17 00:00:00 2001 From: James Rodewig Date: Thu, 7 Nov 2024 09:25:34 -0500 Subject: [PATCH 1/3] docs: Add event feeds to README --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/README.md b/README.md index 89960dda..324fb02b 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,58 @@ if (r.Data.Exists) { ``` +## Event Feeds (beta) + +The driver supports [Event +Feeds](https://docs.fauna.com/fauna/current/learn/cdc/#event-feeds). + +An Event Feed asynchronously polls an [event +source](https://docs.fauna.com/fauna/current/learn/cdc/#create-an-event-source) +for events. + +To get paginated events, pass an [event +source](https://docs.fauna.com/fauna/current/learn/cdc/#create-an-event-source) +or a query that produces an event source to `EventFeedAsync()`: + +```csharp +// Get an event source from a supported Set +EventSource eventSource = await client.QueryAsync(FQL($"Person.all().eventSource()")); + +// Calculate timestamp for 10 minutes ago in microseconds +long tenMinutesAgo = DateTimeOffset.UtcNow.AddMinutes(-10).ToUnixTimeMilliseconds() * 1000; +var feedOptions = new FeedOptions(startTs: tenMinutesAgo, pageSize: 10); + +// Pass the event source and `FeedOptions` to `EventFeedAsync()`: +var feed = await client.EventFeedAsync(eventSource, feedOptions); + +// You can also pass a query that produces an event source directly to `EventFeedAsync()`: +var feedFromQuery = await client.EventFeedAsync(FQL($"Person.all().eventsOn({{ .price, .stock }})"), feedOptions); + +// EventFeedAsync() returns a `FeedEnumerable` instance that can act as an `AsyncEnumerator`. +// You can use `await foreach()` to iterate through all the feed's pages: +await foreach (var page in feed) +{ + foreach (var evt in page.Events) + { + Console.WriteLine($"Event Type: {evt.Type}"); + Person person = evt.Data; + Console.WriteLine($"First Name: {person.FirstName} - Last Name: {person.LastName} - Age: {person.Age}"); + } +} + +// Alternatively, you can use `MoveNextAsync()` to iterate through the feed's pages: +while (await feedFromQuery.MoveNextAsync()) +{ + FeedPage page = feedFromQuery.Current; + foreach (var evt in page.Events) + { + Console.WriteLine($"Event Type: {evt.Type}"); + Person person = evt.Data; + Console.WriteLine($"First Name: {person.FirstName} - Last Name: {person.LastName} - Age: {person.Age}"); + } +} +``` + ## Event Streaming The driver supports [Event Streaming](https://docs.fauna.com/fauna/current/learn/cdc/#event-streaming). From 5e89680537d9ea4b4f0d276f1c0277e47d2cec58 Mon Sep 17 00:00:00 2001 From: James Rodewig Date: Thu, 7 Nov 2024 18:34:17 -0500 Subject: [PATCH 2/3] Address review feedback --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 324fb02b..f6525f36 100644 --- a/README.md +++ b/README.md @@ -319,7 +319,7 @@ var feed = await client.EventFeedAsync(eventSource, feedOptions); var feedFromQuery = await client.EventFeedAsync(FQL($"Person.all().eventsOn({{ .price, .stock }})"), feedOptions); // EventFeedAsync() returns a `FeedEnumerable` instance that can act as an `AsyncEnumerator`. -// You can use `await foreach()` to iterate through all the feed's pages: +// Use `foreach()` to iterate through the feed's pages: await foreach (var page in feed) { foreach (var evt in page.Events) @@ -330,15 +330,18 @@ await foreach (var page in feed) } } -// Alternatively, you can use `MoveNextAsync()` to iterate through the feed's pages: -while (await feedFromQuery.MoveNextAsync()) +// Alternatively, use `NextAsync()` to manually iterate through the feed's pages: +while (await feedFromQuery.NextAsync()) { - FeedPage page = feedFromQuery.Current; - foreach (var evt in page.Events) + FeedPage? page = feedFromQuery.CurrentPage; + if (page != null) { - Console.WriteLine($"Event Type: {evt.Type}"); - Person person = evt.Data; - Console.WriteLine($"First Name: {person.FirstName} - Last Name: {person.LastName} - Age: {person.Age}"); + foreach (var evt in page.Events) + { + Console.WriteLine($"Event Type: {evt.Type}"); + Person person = evt.Data; + Console.WriteLine($"First Name: {person.FirstName} - Last Name: {person.LastName} - Age: {person.Age}"); + } } } ``` From 92dcc05397fa41a143d3a7d35f03459160b4310c Mon Sep 17 00:00:00 2001 From: James Rodewig Date: Fri, 8 Nov 2024 09:43:05 -0500 Subject: [PATCH 3/3] Address review feedback --- README.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f6525f36..c51c83de 100644 --- a/README.md +++ b/README.md @@ -319,7 +319,9 @@ var feed = await client.EventFeedAsync(eventSource, feedOptions); var feedFromQuery = await client.EventFeedAsync(FQL($"Person.all().eventsOn({{ .price, .stock }})"), feedOptions); // EventFeedAsync() returns a `FeedEnumerable` instance that can act as an `AsyncEnumerator`. -// Use `foreach()` to iterate through the feed's pages: +// Use `foreach()` or `NextAsync()` to iterate through the pages of events. + +// Example 1: Use `foreach()` to iterate through feed pages. await foreach (var page in feed) { foreach (var evt in page.Events) @@ -330,20 +332,22 @@ await foreach (var page in feed) } } -// Alternatively, use `NextAsync()` to manually iterate through the feed's pages: -while (await feedFromQuery.NextAsync()) +// Example 2: Use `NextAsync()` to manually iterate through feed pages. +// `NextAsync()` requests the next page: +await feed.NextAsync(); + +if (feedFromQuery.CurrentPage != null && feedFromQuery.CurrentPage.Events.Any()) { - FeedPage? page = feedFromQuery.CurrentPage; - if (page != null) + foreach (var evt in feedFromQuery.CurrentPage.Events) { - foreach (var evt in page.Events) - { - Console.WriteLine($"Event Type: {evt.Type}"); - Person person = evt.Data; - Console.WriteLine($"First Name: {person.FirstName} - Last Name: {person.LastName} - Age: {person.Age}"); - } + Console.WriteLine($"Event Type: {evt.Type}"); + Person person = evt.Data; + Console.WriteLine($"First Name: {person.FirstName} - Last Name: {person.LastName} - Age: {person.Age}"); } } + +// Call `NextAsync()` again to fetch the next page: +await feed.NextAsync(); ``` ## Event Streaming