-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL Server implementation #5
Conversation
Sorry, just a tiny little nudge to let you know I have two more PR's ready (see the checkboxes above) and have updated the PR description above. Take your time. Thanks! |
Thanks @RobThree, awesome work! Really appreciate! I know that in PG But perhaps your "custom" solution would be sufficient enough, too! :) Thanks again, and I tope to be back to you soon! |
As for "how to provision schemas", we typically do it from CI/CD pipelines. Because giving DDL permissions to the service feels just wrong, and the migration story gets too complicated too quickly... Of course, any suggestion to how to make it better is appreciated! |
Understand completely.
I'm fine with leaving it as-is, no problem. However, a compromise could be to have developers opt-in and call some
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RobThree I think it would be good to tidy up the schema files. We shouldnt create the DB here - that should be up to the test fixture (I recommend Test Containers to simplify it too).
@AlexeyRaga I have a question about ordering for the outbox which might require a bit of a think/change for the rowversion
column.
@@ -0,0 +1,5 @@ | |||
IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'kafkaflowtest') | |||
BEGIN | |||
CREATE DATABASE [kafkaflowtest] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should be creating the schema here, not the database. This might work for tests... but wont work for production environments. We cant assume the name of the DB there.
For tests - I'd be looking at using MSSQL Test Containers. @AlexeyRaga would you consider that + DbUp possibly embedded in the code startup (or similar)?
Back to here - I think this should be:
IF NOT EXISTS(SELECT * FROM sys.schemas WHERE name = 'outbox')
BEGIN
CREATE SCHEMA [outbox]
END
There'll be similar changes below too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am happy to take the test containers route.
I have never done it myself though, so can't speak from experience :)
/* Table */ | ||
IF OBJECT_ID(N'[kafkaflowtest].[dbo].[outbox]', N'U') IS NULL | ||
BEGIN | ||
CREATE TABLE [kafkaflowtest].[dbo].[outbox]( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't specify the DB here. And if we change to outbox
as the schema (to keep in line with the PG implementation) that would change to [outbox].[outbox]
e.g:
IF OBJECT_ID(N'[outbox].[outbox]', N'U') IS NULL
BEGIN
CREATE TABLE [outbox].[outbox](
/* Table */ | ||
IF OBJECT_ID(N'[kafkaflowtest].[dbo].[processes]', N'U') IS NULL | ||
BEGIN | ||
CREATE TABLE [kafkaflowtest].[dbo].[processes]( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above with the outbox
table regarding the database name and schema name.
@@ -0,0 +1,5 @@ | |||
IF NOT EXISTS(SELECT * FROM sys.databases WHERE name = 'kafkaflowtest') | |||
BEGIN | |||
CREATE DATABASE [kafkaflowtest] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be setting the schema and not the DB name. As per my comment for the outbox
table
@kchenery As per your database/schema remarks: I agree, will fix that. I am currently working on separating the actual database implementation from the rest of the logic and I'm close to done with that.
I'll update here when I'm done with the code-deduplication / separating RDBMS specific stuff. |
Would anyone have an objection to changing the |
Done.
Schema is fixed here, see 45abefa So, summarizing: I updated the PR request and have 4 branches ready to PR after this one (I could make it a huge PR, but I don't think anyone would enjoy that 😜 ). In order, they are: modernize (no functional changes), lower-framework-support changes required .Net version to .Net Standard 2.0, code-deduplication refactors RDBMS specific stuff to "repositories" (better name suggestions welcome) and mssql-use-schema to use schema's in the integration tests for MSSQL. What's left is:
|
I think it'd be a good change. AFAIK I think we should do it (and write a migration script). What do you think @kchenery ? |
DB change is trivial... its basically just this migration script:
I'm unsure how long that'll take on a large table... but peoples outboxes should be mostly empty. I'll submit a PR for you for that. I haven't looked what code you'd have to change and you'll want to do that first. |
I have already changed the existing scripts and code. I propose we (work on) merge the branches up to now and then see where we stand? (Because I'm kind of losing oversight otherwise 😓 ). It should be alright - as long as you agree with the other changes I made - and then we can add a migration and make final changes (if any) before a new release? Or am I getting ahead of myself? |
It should mostly be empty... But to my knowledge sequences don't get reset even if the rows are deleted from the database... Am I wrong? Also, as @RobThree mentioned, shouldn't it be |
Deletes do not reset serial values. Truncates do not either (unlike SQL Server which does reset the identity values). And no, it should be |
OK, we've merged the @RobThree I guess that we can merge this one too once Kent's suggestions about database/schema are addressed. |
Should be good. Though this still doesn't use a schema (which is in another branch later); have you had a chance to look at the other changes I made? |
Not really, I only at what is in this PR... Can we have the database/schema changes as a part of the PR? Looks like you already have it here so shouldn't be a great trouble? |
No, shouldn't be a problem, I just need to rebase some stuff. Let me see what I can do. |
Done. Should be good to go. |
src/Contrib.KafkaFlow.ProcessManagers.SqlServer/SqlServerProcessManagersStore.cs
Outdated
Show resolved
Hide resolved
Thanks @RobThree, AWESOME contribution! Really appreciated! |
Unfortunately, integration tests are failing... |
Fixed! The new set of packages is released! |
This PR adds a Microsoft SQL Server implementation.
I have 'ported' the Postgres SQL statements to T-SQL as closely as I could. One thing I ran into is that the rowversion mechanism differs quite much between the two. As far as I could see the Outbox doesn't seem to use the rowversion anywhere(?), and I tried to keep the ProcessManager as close to the Postgres version as possible. One of the issues I had was that a rowversion (or timestamp) in Sql Server is an 8 byte (64 bit) value, however, the
VersionedState
requires anint
for the version and since there's no (safe) way to convert a 64 bit value to a 32 bit value I opted to 'DIY' the rowversion; theMERGE
statement should be atomic.It's also not very clear to me what use the
date_added_utc
anddate_updated_utc
fields have, but maybe I'm missing some implementation details that Postgres has that I'm not aware of. I did keep (and populate) them in the Sql Server variant where applicable.Also, there weren't (and aren't) any integrationtests as far as I can see for the Outbox. Again, I tried to keep this as close as possible to the Postgres variant but I haven't tested it (yet).
In the integrationtests project I renamed the
KafkaFlowFixture
to a more specificPostgreKafkaFlowFixture
and then copied it to aSqlServerKafkaFlowFixture
and changed it to work with SqlServer. Same goes for theLifecycleProcessManagerTests
which I renamed toPostgresLifecycleProcessManagerTests
and copied toSqlServerLifecycleProcessManagerTests
and changed to work with SqlServer. This may need some work to de-duplicate (DRY) some of the integrationtests.So, things that need attention:
Since Sql Server (or rather: the
SqlClient
) handles connection pooling internally we don't need to set up a pool like in the Postgres variant. I did, however, have to create a small shared, common library calledContrib.KafkaFlow.SqlServer
which is used by bothKafkaFlow.Outbox.SqlServer
andKafkaFlow.ProcessManagers.SqlServer
. This library only contains a few extension methods to configure Sql Server usage and aSqlServerOptions
record so we don't have to pass a "bare" connectionstring to theSqlServerOutboxBackend
andSqlServerProcessManagersStore
classes.Other than that, I think this should at least be a good start for a SqlServer implementation.
⚠️ I couldn't get the Fixed in 7385102initdb.sh
script to trigger under themssql
container. I have a few solutions/workarounds but I am still deciding which one to use. Your opinion / help would be very much appreciated. For now you'll need to run the/docker-entrypoint-initdb.d/initdb.sh
script manually before running the integrationtests.Oh, one more thing: It isn't very clear to me how you'd use this library in an existing project. I assume the developer is expected to create the
outbox
andprocesses
tables "manually"? I would expect the table(s) creation to be handled either on demand by invoking some method or automatically the first time the database is approached or something?Finally: I have some other ideas / plans:
EDIT: Most of this is done (see this branch). I'll create a new PR for this once this one has been merged.
EDIT: Done; I managed to lower the requirement to .Net Standard 2.0 (see this branch or this commit). This means that even .Net Framework developers can use this library. I'll create a new PR for this once this one and the 'modernize' one (above) has been merged.
EDIT: Done. See this branch