Skip to content

Missing a refresh is possible in ReferenceManager #15831

@viliam-durina

Description

@viliam-durina

Description

I think the code of ReferenceManager.maybeRefresh() might miss a refresh. It tries to avoid starting a refresh if another is already in progress. But I think it's racy:

  1. Thread A calls maybeRefresh(). refreshLock.tryLock returns true and a refresh is started.
  2. When thread A is just before unlock, thread B flushes a new generation and calls maybeRefresh() again. Thread B gets false from refreshLock.tryLock() and does nothing.
  3. Thread A releases the lock
  4. the new generation isn't loaded

I think this optimization is unnecessary and should be removed. The lock should be used only to avoid two threads reloading the same reader, but a refresh notification must not be lost. I think there are two usage scenarios here:

  1. maybeRefresh is called periodically by a single thread
  2. maybeRefresh called after a successful flush or commit: possible loss.

In scenario 1 there are unnecessary calls to maybeRefresh, but never concurrent calls. In scenario 2, there are no unnecessary calls, but calls can be concurrent.

Version and environment details

Current main branch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions