Skip to content

fix: prevent concurrent TGT re-creation race under multi-threaded calls - #3

Merged
metehanboy merged 1 commit into
mainfrom
fix/tgt-race-parallel-calls
Jul 28, 2026
Merged

metehanboy merged 1 commit into
mainfrom
fix/tgt-race-parallel-calls

Conversation

@metehanboy

Copy link
Copy Markdown
Owner

Endpoint.call creates a fresh Authentication() per request, so concurrent (ThreadPoolExecutor) calls from the same process each ran _setup_directories()'s unlocked permission-check/reset and unlocked _test_file_permissions() read - these could delete/recreate the shared tgt_dir/lock files out from under each other, breaking get_tgt()'s own locking and causing every thread to mint its own TGT (observed live: ~20 "Yeni TGT oluşturuldu" log lines within the same second for 20 concurrent calls).

  • _setup_directories(): destructive permission-check/reset now runs at most once per process (double-checked locking via _setup_lock + _verified_temp_dirs), instead of on every Authentication() construction.
  • _test_file_permissions(): tgt_dir/st_dir reads now happen under the same _locked() used by get_tgt()/_store_ticket(), so they can no longer race with a concurrent write.
  • Add regression test simulating 20 concurrent separate Authentication() constructions (matching real Endpoint.call behavior) asserting exactly one TGT is created; fails with FileNotFoundError on the old code.
  • Bump version to 0.7.8-dev.

Değişiklik Açıklaması

Bu PR'ın ne yaptığını açık ve öz bir şekilde açıklayın.

Değişiklik Türü

Lütfen ilgili kutucuğu işaretleyin:

  • Bug fix (hataları düzelten değişiklik)
  • Yeni özellik (geriye uyumlu değişiklik)
  • Breaking change (geriye uyumlu olmayan değişiklik)
  • Dokümantasyon güncellemesi
  • Kod refactoring
  • Performans iyileştirmesi
  • Test ekleme/güncelleme

İlgili Issue

Bu PR hangi issue'yu çözüyor? (varsa)

Closes #

Değişiklik Detayları

Ne Değişti?

  • Değişiklik 1
  • Değişiklik 2
  • Değişiklik 3

Neden Değişti?

Değişikliğin nedenini açıklayın.

Nasıl Test Edildi?

Değişikliklerin nasıl test edildiğini açıklayın:

  • Mevcut testler geçiyor
  • Yeni testler eklendi
  • Manuel test yapıldı
  • Test sonuçları eklendi

Test Sonuçları

# Test komutları ve sonuçları buraya ekleyin
pytest
# Sonuçlar: ...

Ekran Görüntüleri

Varsa, değişiklikleri gösteren ekran görüntüleri ekleyin.

Kontrol Listesi

PR göndermeden önce aşağıdakileri kontrol edin:

  • Kodumu formatladım (black, isort)
  • Mevcut testler geçiyor
  • Yeni testler ekledim (eğer gerekiyorsa)
  • Dokümantasyonu güncelledim (eğer gerekiyorsa)
  • Commit mesajlarım açıklayıcı
  • Kod standartlarına uyuyorum
  • Type hints ekledim (mümkünse)
  • Docstring'ler ekledim (mümkünse)

Breaking Changes

Bu PR breaking change içeriyor mu?

  • Evet (aşağıda açıklayın)
  • Hayır

Breaking Changes Detayları

Eğer breaking change varsa, detaylarını açıklayın:

  • Ne değişti?
  • Kullanıcılar ne yapmalı?

Ek Notlar

Eklemek istediğiniz başka bir şey var mı?

Review Notları

Reviewer'lar için özel notlar (varsa):

Endpoint.__call__ creates a fresh Authentication() per request, so
concurrent (ThreadPoolExecutor) calls from the same process each ran
_setup_directories()'s unlocked permission-check/reset and unlocked
_test_file_permissions() read - these could delete/recreate the shared
tgt_dir/lock files out from under each other, breaking get_tgt()'s own
locking and causing every thread to mint its own TGT (observed live:
~20 "Yeni TGT oluşturuldu" log lines within the same second for 20
concurrent calls).

- _setup_directories(): destructive permission-check/reset now runs at
  most once per process (double-checked locking via _setup_lock +
  _verified_temp_dirs), instead of on every Authentication() construction.
- _test_file_permissions(): tgt_dir/st_dir reads now happen under the
  same _locked() used by get_tgt()/_store_ticket(), so they can no
  longer race with a concurrent write.
- Add regression test simulating 20 concurrent separate Authentication()
  constructions (matching real Endpoint.__call__ behavior) asserting
  exactly one TGT is created; fails with FileNotFoundError on the old code.
- Bump version to 0.7.8-dev.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@metehanboy
metehanboy merged commit b1c1341 into main Jul 28, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant