#527: remove global caching for fb/github_graph, inject octo into over?#556
#527: remove global caching for fb/github_graph, inject octo into over?#556VasilevNStas wants to merge 1 commit into
Conversation
|
@yegor256 please re-review |
cdf6d81 to
18b72e3
Compare
|
The |
bibonix
left a comment
There was a problem hiding this comment.
The branch sits on top of 8e52719, 17 commits behind master, and the resulting diff folds in unrelated history rather than only the #527 change. Concretely, the diff shows lib/fbe/fake_octokit.rb being removed (1797 lines) and re-inlined into lib/fbe/octo.rb (~1791 additions), because fake_octokit was extracted on master in #534 after this branch forked off. The same staleness pulls test deletions in test_delete.rb, test_delete_one.rb, test_overwrite.rb, test_just_one.rb, test_kill_if.rb, test_repeatedly.rb, test_sec.rb, test_unmask_repos.rb, test_octo.rb, and test_sqlite_store.rb that revert improvements already landed in #503, #517, #521, #531, #532, #533, #534, #541, #543, #545, and #548, plus README, .gitignore, .github/workflows/actionlint.yml, and .github/workflows/codecov.yml changes that have nothing to do with #527. xcop is red on the current head. Rebase onto current master and drop everything outside lib/fbe/fb.rb, lib/fbe/github_graph.rb, lib/fbe/octo.rb, lib/fbe/over.rb, lib/fbe/iterate.rb, lib/fbe/unmask_repos.rb, then resubmit. No inline comments yet because the rebase will rewrite the diff.
18b72e3 to
b3eda66
Compare
|
@VasilevNStas again, a wrong move. we do need caching and we do need mutex. I suggest keeping mutex inside the |
|
@VasilevNStas merge conflicts here |
|
Please fix the merge conflicts so this pull request can be merged. |
This is a new PR replacing the closed #535. The approach was changed after @yegor256 rejected
GLOBAL_MUTEX("global state is pure evil in OOP").Problem
lib/fbe/octo.rb:53,lib/fbe/fb.rb:34,lib/fbe/github_graph.rb:18useglobal[:x] ||= begin...end— a non-atomic read-then-write. Under concurrent access (e.g., multiple judges running in parallel), two threads can both evaluate the block and overwrite each other's result.Solution
Changes made:
lib/fbe/fb.rb— removedglobal[:fb] ||=. Each call toFbe.fb()creates a fresh decorator stack. Thread-safe by definition, no global state.lib/fbe/github_graph.rb— removedglobal[:github_graph] ||=. Same approach — each call creates a new GraphQL client.lib/fbe/octo.rb— keptglobal[:octo] ||=. Without caching, rate limit tracking breaks:Fbe::Middleware::RateLimitstores state per middleware instance. Different clients don't share request history, sooff_quota?always returnsfalseon a fresh client.lib/fbe/over.rb— added optionalocto:parameter. When provided, uses it foroff_quota?check; otherwise falls back toFbe.octo()(backward compatibility).lib/fbe/iterate.rb— passesocto: oct(its internal client) to allFbe.over?calls. Proper OOP: dependency injection instead of global cache.lib/fbe/unmask_repos.rb— createsoctobefore the firstFbe.over?call and passes it viaocto:.Why not remove caching from octo.rb entirely?
Fbe::Middleware::RateLimitis a Faraday middleware living inside each Octokit client's Faraday stack. It tracks@remaining(requests left before hitting rate limit) and decrements it on each request. If everyFbe.octocall creates a new client with fresh middleware, rate limit tracking stops working —off_quota?always sees a fresh/rate_limitresponse.The clean OOP fix would be full DI (create the client once and pass it everywhere), but that requires changing the judge API. Our compromise:
octo.rbremains a cached factory, while all internal callers (iterate,unmask_repos,over?) accept and passocto:explicitly.Tests