lukas-krecan / ShedLock

Distributed lock for your scheduled tasks
Apache License 2.0
3.58k stars 508 forks source link

Add a ShedLock provider for GCP Spanner #691

Open surfsoft opened 3 years ago

surfsoft commented 3 years ago

Is your feature request related to a problem? Please describe. My team is planning to migrate our Spring based services, which make use of ShedLock, to use Spanner databases using the spring-cloud-gcp-data-spanner module provided by Google. Platform choices mean that we are unable to use JDBC and are therefore unable to use the JDBC template provider, which appears to be the only provider that is capable of supporting Spanner at this time.

Describe the solution you'd like We'd like to use a provider that is compatible with and dependent upon the Spring Cloud GCP Data Spanner module without the need to add any JDBC dependencies and configuration.

Describe alternatives you've considered We've considered using only the JDBC template as a database connection but this is not the preferred approach of the client and prevents us from using Spanner to maximum effect. We've also looked at using JDBC just for ShedLock and a different Spring Cloud GCP Data Spanner connection for everything else, but this has its own performance impact.

Additional context The spring-cloud-gcp-data-spanner module is provided by Google as part of the spring-cloud-gcp project: https://github.com/spring-cloud/spring-cloud-gcp

lukas-krecan commented 3 years ago

Hi, thanks for feedback. Unfortunattely I do not have capacity to implement it, but I accept pull-requests 😈 It's quite easy to impement a LockProvider, just mimic some of the existing providers that is similar to the Data Spanner.

surfsoft commented 3 years ago

Hi Lukas, thanks for the rapid feedback. We will look into the possibility of doing this and get back to you.

surfsoft commented 2 years ago

We've completed an implementation but it hasn't been fully tested against spanner yet.

badmusamuda commented 7 months ago

To use spanner with ShedLock.

  1. Define your shedlock table structure as you desire

`

        <column name="locked_at" type="timestamp"/>
        <column name="locked_by" type="VARCHAR(255)"/>
        <column name="name" type="VARCHAR(255)">
            <constraints nullable="false" primaryKey="true"/>
        </column>`
  1. Create your Spanner Datasource config

`@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = { "your_packages_here" }, entityManagerFactoryRef = "spannerEntityManagerFactory", transactionManagerRef = "spannerPlatformTransactionManager") public class SpannerDataSourceConfig {

@Value("${spring.datasource.url}")
private String datasourceUrl;
//... other variable
@Value("${spring.liquibase.change-log}")
private String liquidBaseChangeLog;

@Bean("spannerDataSource")
public DataSource spannerDatasource() {
    var dataSource = new JdbcDataSource();
    dataSource.setUrl(datasourceUrl);
    return dataSource;
}
//... other beans

@Bean(name = "spannerLiquibase")
public SpringLiquibase spannerLiquibase(){
    var liquidBase = new SpringLiquibase();
    liquidBase.setDataSource(spannerDatasource());
    liquidBase.setChangeLog(liquidBaseChangeLog);
    return liquidBase;
}`
  1. Define your ShedLockConfig

    `@RequiredArgsConstructor public class ShedLockConfig {

    private final SpannerDataSourceConfig spannerDataSourceConfig;

    @Bean public LockProvider lockProvider() { return new JdbcTemplateLockProvider( JdbcTemplateLockProvider.Configuration.builder() .withTableName("your_shed_lock_table_name") .withJdbcTemplate(new JdbcTemplate(spannerDataSourceConfig.spannerDatasource())) //DO NOT INCLUDE THE dbWithTime since it does not work with spanner timestamp .build() ); }

}`