Skip to content

JAVA-1126: Mapper should be resilient when table or UDT is modified.#678

Merged
olim7t merged 1 commit into
3.0.xfrom
java1126
Jul 8, 2016
Merged

JAVA-1126: Mapper should be resilient when table or UDT is modified.#678
olim7t merged 1 commit into
3.0.xfrom
java1126

Conversation

@adutra
Copy link
Copy Markdown
Contributor

@adutra adutra commented May 23, 2016

This PR proposes the following enhancements:

  • Each mapping manager subscribes to schema change events and reacts to table and UDT removed / modified notifications (could extend to keyspace notifications too); the basic reaction consists of a log waning;
  • For modified UDTs, the manager also tries to update the previously registered MappedUDTCodec with a new one;
  • Column names and field names are validated upfront (upon creation of a Mapper) in a fail-fast attempt to detect wrong configurations;
  • Existence of tables and UDTs are also validated upfront.

This however cannot prevent existing Mapper instances from misbehaving, i.e. if a user creates a Mapper instance, then issues an ALTER statement, that Mapper instance would be stale and most likely, unusable.

@adutra adutra modified the milestones: 3.0.1, 3.0.3 May 23, 2016
public void onTableRemoved(TableMetadata table) {
synchronized (mappers) {
Iterator<Mapper<?>> it = mappers.values().iterator();
while (it.hasNext()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not a regular for-each loop?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nevermind, I hadn't noticed the remove() call.

@adutra
Copy link
Copy Markdown
Contributor Author

adutra commented Jun 28, 2016

Squashed and rebased on top of current 3.0.x.

}

@Override
public void onTableChanged(TableMetadata current, TableMetadata previous) {
Copy link
Copy Markdown
Contributor

@tolbertam tolbertam Jun 29, 2016

Choose a reason for hiding this comment

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

On the case of a user type being changed, it looks like it's removed from mappers, but then readded via getUDTCodec, but this doesn't do the same for table via getMapper, should it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah maybe it is needed in the UDT case because it updates the Codec, where no analog is needed for table. I suppose only benefit is maybe we'd be able to log the error here instead of when the user tries to use the mapper.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I suppose the other issue is replacing the Mapper doesn't do a lot of good since the user would still hold a reference to the old one so it makes sense to not attempt to replace it.

@tolbertam
Copy link
Copy Markdown
Contributor

rebased (3.0.x had some test fixes) and added some tests and documentation. I also made a slight change so IllegalArgumentException is thrown instead of IllegalStateException in the case where you attempt to create a UDT codec where the UDT doesn't exist in metadata to be consistent with other error cases. Feel free to squash.

lgtm 👍 assuming CI looks good.

mapper.addColumns(
createColumnMappers(pks, factory, mapper.entityClass, mappingManager, columnCounter, tableMetadata, ksName, tableName),
createColumnMappers(ccs, factory, mapper.entityClass, mappingManager, columnCounter, tableMetadata, ksName, tableName),
createColumnMappers(rgs, factory, mapper.entityClass, mappingManager, columnCounter, tableMetadata, ksName, tableName));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ksName and tableName could be retrieved from tableMetadata instead of passing them as parameters (also applies to createFieldMappers below).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's true but frankly I prefer to leave it as is for practical reasons:

  1. Quoting of case-sensitive identifiers is not very consistent, and is done in different places, so should we quote or not the result of TableMetadata.getName()? The code coverage for case-sensitive use cases is not very good, so let's not introduce regressions for that.
  2. In JAVA-541 + JAVA-636 + JAVA-984: Polymorphism support to object mapper #686 I added specific tests for case-sensitiveness and also applied a methodic quoting of identifiers). See btw JAVA-564.
  3. The less we modify this class the easier it will be to merge it with JAVA-541 :)

@adutra
Copy link
Copy Markdown
Contributor Author

adutra commented Jul 7, 2016

added some tests and documentation.

Great tests, thanks for that!

The mapping manager subscribes to schema change events and reacts to
table and UDT removed / modified notifications: a warning is logged and,
for modifications, the manager tries to replace the mapper or codec with
a new one (which may or may not work depending on the nature of the
change and whether client code kept a reference to the old mapper
instance).

In addition, table/UDT names and column/field names are validated
earlier, in a fail-fast attempt to detect wrong configurations.
@olim7t olim7t merged commit 74d0201 into 3.0.x Jul 8, 2016
@olim7t olim7t deleted the java1126 branch July 8, 2016 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants