Skip to content

Connection not closed after migration when using NodaTime #3560

Closed

Description

@marcusber

I've struggled for a while to understand why I see a connection open. after a migration. It took me a while to understand that it was UseNodaTime() that was behind it.

Here's a program reproducing the error.

I've tried to a bit to troubleshoot the problem and found two things in efcore.pg that may be related. When both was applied, the connection left the pool, but was still open towards the db.
Posting those as separate PRs so you could the determine the relevance.

Activity

  1. added theissue type on Jun 30, 2025
  2. added this to the 9.0.5 milestone on Jun 30, 2025
  3. added 2 commits that reference this issue on Jun 30, 2025
    fb96538
    5014ee6
  4. marcusber commented on Jun 30, 2025

    @marcusber
    ContributorAuthor

    @roji Unfortunately the #3561 doesn't resolve this issue.

  5. roji commented on Jun 30, 2025

    @roji
    Member

    You mean the program you posted above still fails?

  6. reopened this on Jun 30, 2025
  7. marcusber commented on Jun 30, 2025

    @marcusber
    ContributorAuthor

    Yes, I did those changes locally and it still fails.

  8. marcusber commented on Jun 30, 2025

    @marcusber
    ContributorAuthor

    Ok, I've come a bit further. The difference lies in when the DataReader for the migration is added.
    When not using noda time, no plugins are available and the DataSource null is returned.

    _ when _plugins.Any() => GetSingletonDataSource(npgsqlOptionsExtension),
    // If there's no configured feature which requires us to use a data source internally, don't use one; this causes
    // NpgsqlRelationalConnection to use the connection string as before (no data source), allowing switching connection strings
    // with the same service provider etc.
    _ => null

    When NodaTime is added on the other hand, a brand new DataSource is created from NpgsqlSlimDataSourceBuilder through CreateDataSource via GetSingletonDataSource.

    But I have trouble getting the my head around the NpgsqlDataSourceManager. Is the idea to eventually replace the static pool in npgsql? Would it be an idea to have an operator on that class that allows clearing the datasources?

    What I'm eventually after is to allow a database to be migrated. Operate on the database in exclusive mode and the be allowed to to connect to it once again. If I kill the connection, it will still be available in the PoolingDataSource and it has no idea that it has been killed and tries to reuse it. When reused it will of course throw, since it is no longer connected. I don't know if the idea here is to detect that and re-create the connection from the datasource?

    I would love to read what you have to share on the subject @roji .

  9. marcusber commented on Jul 4, 2025

    @marcusber
    ContributorAuthor

    @roji Just i gentle reminder if the notification was lost in your busy notification flow.

  10. marcusber commented on Sep 3, 2025

    @marcusber
    ContributorAuthor

    Using the data source definition gives me the desired behavior.

    public static DbContextOptionsBuilder<TContext> UseNpgsql<TContext>(
    this DbContextOptionsBuilder<TContext> optionsBuilder,
    DbDataSource dataSource,
    Action<NpgsqlDbContextOptionsBuilder>? npgsqlOptionsAction = null)
    where TContext : DbContext
    => (DbContextOptionsBuilder<TContext>)UseNpgsql(
    (DbContextOptionsBuilder)optionsBuilder, dataSource, npgsqlOptionsAction);

    Closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions