simpleidserver / EFCore.Cassandra

Entity Framework Core provider for Cassandra
Apache License 2.0
35 stars 16 forks source link

Small issue in Code First migration flow #19

Closed Delta-38 closed 3 years ago

Delta-38 commented 3 years ago

Hi, When using code first migrations I've run into an issue where the ReplicationFactor doesn't follow the one set in configuration.

Initially I thought this could be due to the need for Migration History table and schema needing to be created in advance of the table configurations.

In my use context, the DbContext get initialized with the UseCassandra extension in my app startup and a hosted service then oversees a call to context.Database.MigrateAsync. And the schema / tables to be created are specified in my OnModelCreating options.

TL;DR; EFCore.Cassandra 2.0.4 uses a KeyspaceSimpleReplicationStrategy with a replica factor of 2 regardless of settings. (In my case I needed it to be 1.) Also, currently if setting a custom tablename, schema for the MigrationHistoryTable this gets ignored.

Brief code excerpts for clarity's sake: From the Startup: services.AddDbContext<CassandraDbContext>(options => { options.UseCassandra(connectionBuilder.ConnectionString, cassandraConfiguration.KeySpace, cOpts => { cOpts.MigrationsAssembly(typeof(CassandraDbContext).Assembly.FullName); });

From the DbContext class: protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.EnsureKeyspaceCreated(new KeyspaceReplicationSimpleStrategyClass(1)); modelBuilder.ApplyConfiguration(new SomeTable()); modelBuilder.ApplyConfiguration(new SomeOtherTable());

This can cause an issue with the replication strategy: Because if the keyspace and the migration history table don't exist at the beginning, then the keyspace will be created disregarding the desired replication strategy.

I noticed this only when going into kubernetes since strangely despite EF Core logging: CREATE KEYSPACE IF NOT EXISTS "myKeyspace" WITH REPLICATION = { 'class' : 'SimpleStrategy' , 'replication_factor' : 1 }

a Describe keyspace myKeyspace would show replication_factor: 2.

Looking into the Cassandra server logs I found that this was going on (Sorry for the lengthy post): Create new Keyspace: KeyspaceMetadata{name=myKeyspace, params=KeyspaceParams{durable_writes=true, replication=ReplicationParams{class=org.apache.cassandra.locator.SimpleStrategy, replication_factor=2}}, tables=[], views=[], functions=[], types=[]} Create new table: org.apache.cassandra.config.CFMetaData@20396ec8[cfId=a7832b50-491e-11eb-a7db-9b89c16b65a4,ksName=myKeyspace,cfName=EFMigrationsHistory,flags=[COMPOUND],par...(omitted for sanity's sake)Initializing myKeyspace.EFMigrationsHistory

I also tried specifying the implementation of ICassandraHistoryRepository so as to return a different schema name for the migration table, but it appears to be deeper than that. I am not sure where it is being set.

In my case this caused an issue due to my Dev Cassandra only being specced to replica 1, but as it is either I can't figure out how to get it to do it.

Thanks in advance,

simpleidserver commented 3 years ago

Hi,

The issue has been fixed in the branch "release/2.0.5". There was an issue in the class "CassandraHistoryRepository", in fact this class didn't take into account the configuration like replication_factor. Can-you try again with the latest changes committed in the branch "release/2.0.5"

Delta-38 commented 3 years ago

Hi, sorry for the long delay, I have finally managed to test the behavior of the 2.0.5 branch. It now correctly creates everything with the expected replication factor.

I have run into a separate issue (dbset, udt mapping) but will open a separate issue for it. Thanks, looking forward to the 2.0.5 release.