Skip to content

Conversation

sophiatev
Copy link
Contributor

@sophiatev sophiatev commented Aug 5, 2020

Outlines the preliminary design of the trigger binding, including

  • Creating the worker table if one does not exist for a given user table
  • Detecting new changes made to rows in a user table using the change table/worker table
  • Acquiring leases on the modified rows in the user table
  • Renewing leases while processing occurs
  • Triggering a user's function based on the modified rows
  • Releasing leases after a successful trigger, and then continuing to poll for changes

I still haven't implemented functionality to periodically cleanup the worker table (similar to how SQL cleans up the change table). And I haven't started any work related to the scale controller.
Design doc that the trigger binding is based on.

Copy link
Member

@cgillum cgillum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to see this progress! Some quick comments based on what I've read so far:

Copy link
Member

@cgillum cgillum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round two of feedback. I still have more code to get through but hopefully this is useful feedback to start thinking about.

Copy link
Contributor

@glennamanns glennamanns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, this was a lot of code. Overall, really nice job. Super exciting that you've gotten this working!! :)

Main points:

  • I'm worried about how many SQL commands we have to run to retrieve all of the data, renew/acquire/release leases, etc. Have you had a chance to stress test this (particularly with more than one Functions host running at once?)
  • Partially in response to ^, I think we should support some type of IEnumerable<SqlChangeTrackingEntry> to reduce at least some of the trips to SQL
  • More tests/examples

[SqlTrigger("Products", ConnectionStringSetting = "SqlConnectionString")] IEnumerable<SqlChangeTrackingEntry<Product>> changes,
ILogger logger)
{
foreach (var change in changes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try to come up with more complicated examples (+ tests) that use the Trigger to make sure we've covered a wide range of customer scenarios. @anthonychu might be able to help with this, but some ideas:

  • trigger plus input binding to retrieve data about the rows that have changed (not just the PKs). Maybe we trigger on changes to the Customers table, retrieve data about the Customer using the input binding, and then send a welcome "email" if it's an insert

  • trigger where order matters. Say we're triggering on changes to the Orders table, which has a Foreign Key to the Customers table. One use case could be to process all the changes to a particular Customer in order. I don't think we support this today, but it would be good to keep it in mind / have as a goal if we think users might want this

/// <returns>The query</returns>
private async Task<string> BuildCreateTableCommandStringAsync()
{
await GetPrimaryKeysAsync();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

things are going to get really weird if the customer changes the PKs on their user table.. although I guess the change tracking table will also get messed up - do you know how SQL handles that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this as well. I couldn't find anything in the Change Tracking docs about this, but when I tried to change the primary key constraint on one of my tables by first deleting it and then creating another constraint, Change Tracking prevented me from deleting it. From what I understand, this is the only way to mess with primary key constraints since it doesn't seem like you can add another primary key constraint after one already exists. That's what this doc made it seem like at least.

Copy link
Member

@cgillum cgillum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed everything except SqlTableWatcher.cs (I wanted to save that one for last 😄). See feedback below - mostly minor stylistic stuff.

@sophiatev sophiatev merged commit 8f932c2 into dev Aug 14, 2020
@cgillum cgillum deleted the triggerbinding branch August 15, 2020 00:16
PBBlox pushed a commit to PBBlox/azure-functions-sql-extension that referenced this pull request Apr 6, 2025
Preliminary Design of Trigger Binding
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants