Skip to content

feat(activesync): persist folder UID map across FolderSync resets#87

Open
TDannhauer wants to merge 1 commit into
FRAMEWORK_6_0from
feat/persistent-folder-uid-map
Open

feat(activesync): persist folder UID map across FolderSync resets#87
TDannhauer wants to merge 1 commit into
FRAMEWORK_6_0from
feat/persistent-folder-uid-map

Conversation

@TDannhauer

Copy link
Copy Markdown
Contributor

Summary

  • Persist SyncCache foldermap (backend_serverideas_folder_uid) across FolderSync rebuilds
  • Stop Sql/Mongo FolderSync synckey=0 reset from clearing/saving an empty folders map mid-rebuild
  • Resolve collection UIDs via foldermap when the volatile folders entry is missing; reconcile after export
  • Document the approach in doc/todo.md; unit coverage in FolderUidMapPersistenceTest

Motivation

Concurrent iOS ActiveSync sessions often issue FolderSync with synckey=0 after hierarchy changes. Clearing and persisting an empty folders map raced parallel SYNC/PING into FolderGone / unstable sync. Deterministic UID generation (#81) mitigated divergent UIDs but not map loss on clear.

Independent of streaming (#84) and idempotent import (#86). Touches the same State/{Base,Sql,Mongo}.php files as #86 in different regions — rebase if both merge closely.

Changes

  • SyncCache: foldermap, seed/reconcile helpers; clearFolders() keeps the map
  • State Sql/Mongo: FolderSync reset keeps folders + foldermap
  • State_Base: prefer foldermap in getFolderUidToBackendIdMap(); rememberFolderUid / resetFolderUidMap
  • Collections / FolderSync: lookup fallback and post-export reconcile
  • doc/todo.md, FolderUidMapPersistenceTest

Test plan

  • FolderUidMapPersistenceTest (deployment PHPUnit)
  • Live soak: iPhone account re-add — FolderSync logs keeping folders + foldermap; no ghost folder / status 12 during initial sync
  • Concurrent FolderSync synckey=0 while SYNC/PING run — no FolderGone storm for known UIDs
  • Rename/delete folder — foldermap updates; deleted UIDs pruned on reconcile

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

🔍 CI Results

Overall: ❌ 12/12 lanes failed

TL;DR: ❌ Quality issues: PHPUnit: 60 tests failed; PHPStan: 330 unique errors in 8 lanes; PHP-CS-Fixer: 23 files.

Summary by PHP Version

PHP dev stable
8.0
8.1
8.2
8.3
8.4
8.5

Quality Metrics

  • PHPUnit: 16 failures, 44 errors out of 230 tests in 8 lanes ❌
    Per-test detail in the table below. Raw JUnit XML and JSON are uploaded as workflow artifacts.

    Which tests failed
    Type Test Lanes Message
    ❌ failure Horde\ActiveSync\AppointmentTest::testSetRecurrenceEas16SetsFirstDayOfWeek php8.2-dev, php8.2-stable, php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [PHPUnit\Framework\ExpectationFailedException] Failed asserting that '' matches expected 0.
    ⚠️ error Horde\ActiveSync\FolderUidDeterministicTest::testFolderUidIsDeterministicAcrossDriverInstances php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [Error] Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::getMockForAbstractClass()
    ⚠️ error Horde\ActiveSync\FolderUidDeterministicTest::testFolderUidIsDeterministicForRepeatedLookups php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [Error] Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::getMockForAbstractClass()
    ⚠️ error Horde\ActiveSync\FolderUidDeterministicTest::testFolderUidUsesPersistedMapWhenPresent php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [Error] Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::getMockForAbstractClass()
    ⚠️ error Horde\ActiveSync\FolderUidMapPersistenceTest::testStateMapPrefersPersistedFolderMap php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [Error] Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::getMockForAbstractClass()
    ⚠️ error Horde\ActiveSync\Request\FindRequestTest::testMockDriverReturnsSuccessfulEmptyFindResults php8.2-dev, php8.2-stable, php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [InvalidArgumentException] Missing required state object
    ❌ failure Horde\ActiveSync\Request\FindRequestTest::testParseFindRangeHonorsClientWindow php8.2-dev, php8.2-stable, php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [PHPUnit\Framework\ExpectationFailedException] Failed asserting that 100 is identical to 101.
    ⚠️ error Horde\ActiveSync\SyncTimeBudgetTest::testGetSyncConfigDefaultsToEmptyArray php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [Error] Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::getMockForAbstractClass()
    ⚠️ error Horde\ActiveSync\SyncTimeBudgetTest::testGetSyncConfigReturnsConfiguredValues php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [Error] Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::getMockForAbstractClass()
  • PHPStan (advisory): 330 unique errors in 8 lanes ⚠️

  • PHP-CS-Fixer: 23 unique files with issues (of 202 checked) ⚠️

❌ Failed Lanes

php8.0-dev

  • PHPUnit: ❌ Setup failed (No result file found)
  • PHPStan: ❌ Setup failed (No result file found)

php8.0-stable

  • PHPUnit: ❌ Setup failed (Composer install failed in /tmp/horde-ci/lanes/php8.0-stable/ActiveSync: Your requirements could not be resolved to an installable set of packages.)
  • PHPStan: ❌ Setup failed (Composer install failed in /tmp/horde-ci/lanes/php8.0-stable/ActiveSync: Your requirements could not be resolved to an installable set of packages.)

php8.1-dev

  • PHPUnit: ❌ Setup failed (No result file found)
  • PHPStan: ❌ Setup failed (No result file found)

php8.1-stable

  • PHPUnit: ❌ Setup failed (No result file found)
  • PHPStan: ❌ Setup failed (No result file found)

php8.2-dev

  • PHPUnit: 2 failures, 1 error

php8.2-stable

  • PHPUnit: 2 failures, 1 error

php8.3-dev

  • PHPUnit: 2 failures, 7 errors

php8.3-stable

  • PHPUnit: 2 failures, 7 errors

php8.4-dev

  • PHPUnit: 2 failures, 7 errors
  • PHP-CS-Fixer: 23 files with issues

php8.4-stable

  • PHPUnit: 2 failures, 7 errors

php8.5-dev

  • PHPUnit: 2 failures, 7 errors

php8.5-stable

  • PHPUnit: 2 failures, 7 errors

CI powered by horde-componentsView full results

Keep backend-id to EAS-uid assignments in SyncCache foldermap and stop
FolderSync synckey=0 from clear+saving an empty folders map so concurrent
SYNC/PING do not hit FolderGone. Reconcile stale folders after a full
hierarchy export.
@TDannhauer
TDannhauer force-pushed the feat/persistent-folder-uid-map branch from 274755d to 66d338d Compare July 19, 2026 19:51
@TDannhauer
TDannhauer requested a review from ralflang July 19, 2026 19:54
@TDannhauer

TDannhauer commented Jul 19, 2026

Copy link
Copy Markdown
Contributor Author

@ralflang please review and merge, then all current side topics of AS are closed and i can rebase #86 and proceed there with the user

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