Scylla Documentation Logo Documentation
  • Server
    • Scylla Open Source
    • Scylla Enterprise
    • Scylla Alternator
  • Cloud
    • Scylla Cloud
    • Scylla Cloud Docs
  • Tools
    • Scylla Manager
    • Scylla Monitoring Stack
    • Scylla Operator
  • Drivers
    • CQL Drivers
    • DynamoDB Drivers
Download
Menu

Caution

You're viewing documentation for a previous version of Scylla Java Driver. Switch to the latest stable version.

Scylla Java Driver Manual Developer docs Common infrastructure Driver context

Driver context¶

The context holds the driver’s internal components. It is exposed in the public API as DriverContext, accessible via session.getContext(). Internally, the child interface InternalDriverContext adds access to more components; finally, DefaultDriverContext is the implementing class.

The dependency graph¶

Most components initialize lazily (see LazyReference). They also reference each other, typically by taking the context as a constructor argument, and extracting the dependencies they need:

public DefaultTopologyMonitor(InternalDriverContext context) {
  ...
  this.controlConnection = context.getControlConnection();
}

This avoids having to handle the initialization order ourselves. It is also convenient for unit tests: you can run a component in isolation by mocking all of its dependencies.

Obviously, things won’t go well if there are cyclic dependencies; if you make changes to the context, you can set a system property to check the dependency graph, it will throw if a cycle is detected (see CycleDetector):

-Dcom.datastax.oss.driver.DETECT_CYCLES=true

This is disabled by default, because we don’t expect it to be very useful outside of testing cycles.

Why not use a DI framework?¶

As should be clear by now, the context is a poor man’s Dependency Injection framework. We deliberately avoided third-party solutions:

  • to keep things as simple as possible,

  • to avoid an additional library dependency,

  • to allow end users to access components and add their own (which wouldn’t work well with compile-time approaches like Dagger).

Overriding a context component¶

The basic approach to plug in a custom internal component is to subclass the context.

For example, let’s say you wrote a custom NettyOptions implementation (maybe you have multiple sessions, and want to reuse the event loop groups instead of recreating them every time):

public class CustomNettyOptions implements NettyOptions {
  ...
} 

In the default context, here’s how the component is managed:

public class DefaultDriverContext {
  
  // some content omitted for brevity
  
  private final LazyReference<NettyOptions> nettyOptionsRef =
      new LazyReference<>("nettyOptions", this::buildNettyOptions, cycleDetector);

  protected NettyOptions buildNettyOptions() {
    return new DefaultNettyOptions(this);
  }

  @NonNull
  @Override
  public NettyOptions getNettyOptions() {
    return nettyOptionsRef.get();
  }
}

To switch in your implementation, you only need to override the build method:

public class CustomContext extends DefaultDriverContext {

  public CustomContext(DriverConfigLoader configLoader, ProgrammaticArguments programmaticArguments) {
    super(configLoader, programmaticArguments);
  }

  @Override
  protected NettyOptions buildNettyOptions() {
    return new CustomNettyOptions(this);
  }
}

Then you need a way to create a session that uses your custom context. The session builder is extensible as well:

public class CustomBuilder extends SessionBuilder<CustomBuilder, CqlSession> {

  @Override
  protected DriverContext buildContext(
      DriverConfigLoader configLoader, ProgrammaticArguments programmaticArguments) {
    return new CustomContext(configLoader, programmaticArguments);
  }

  @Override
  protected CqlSession wrap(@NonNull CqlSession defaultSession) {
    // Nothing to do here, nothing changes on the session type
    return defaultSession;
  }
}

Finally, you can use your custom builder like the regular CqlSession.builder(), it inherits all the methods:

CqlSession session = new CustomBuilder()
    .addContactPoint(new InetSocketAddress("1.2.3.4", 9042))
    .withLocalDatacenter("datacenter1")
    .build();
PREVIOUS
Concurrency
NEXT
Event bus
  • 4.10.0.x
    • 4.13.0.x
    • 4.12.0.x
    • 4.11.1.x
    • 4.10.0.x
    • 4.7.2.x
    • 3.11.2.x
    • 3.11.0.x
    • 3.10.2.x
    • 3.7.2.x
  • Java Driver for Scylla and Apache Cassandra®
  • API Documentation
  • Manual
    • API conventions
    • Case sensitivity
    • Core driver
      • Address resolution
      • Asynchronous programming
      • Authentication
      • Bill of Materials (BOM)
      • Compression
      • Configuration
        • Reference configuration
      • Control connection
      • Custom codecs
      • Detachable types
      • Query idempotence
      • Integration
      • Load balancing
      • Logging
      • Metadata
        • Node metadata
        • Schema metadata
        • Token metadata
      • Metrics
      • Native protocol
      • Non-blocking programming
      • Paging
      • Performance
      • Connection pooling
      • Query timestamps
      • Reactive Style Programming
      • Reconnection
      • Request tracker
      • Retries
      • Using the shaded JAR
      • Speculative query execution
      • SSL
      • Statements
        • Batch statements
        • Per-query keyspace
        • Prepared statements
        • Simple statements
      • Temporal types
      • Request throttling
      • Query tracing
      • Tuples
      • User-defined types
    • Developer docs
      • Administrative tasks
      • Common infrastructure
        • Concurrency
        • Driver context
        • Event bus
      • Native protocol layer
      • Netty pipeline
      • Request execution
    • Mapper
      • Integration
        • Kotlin
        • Lombok
        • Java 14 Records
        • Scala
      • DAOs
        • Custom result types
        • Delete methods
        • GetEntity methods
        • Increment methods
        • Insert methods
        • Null saving strategy
        • Query methods
        • Query provider methods
        • Select methods
        • SetEntity methods
        • Statement attributes
        • Update methods
      • Entities
      • Mapper interface
    • OSGi
    • Query builder
      • Conditions
      • DELETE
      • Idempotence in the query builder
      • INSERT
      • Relations
      • Schema builder
        • Aggregate
        • Function
        • Index
        • Keyspace
        • Materialized View
        • Table
        • Type
      • SELECT
      • Terms
      • TRUNCATE
      • UPDATE
  • Upgrade guide
  • Frequently asked questions
  • Changelog
  • Create an issue
  • Edit this page

On this page

  • Driver context
    • The dependency graph
    • Why not use a DI framework?
    • Overriding a context component
Logo
Docs Contact Us About Us
Mail List Icon Slack Icon
© 2022, ScyllaDB. All rights reserved.
Last updated on 25 May 2022.
Powered by Sphinx 4.3.2 & ScyllaDB Theme 1.2.2