KamoCRM

Member_rights_applied writes only the difference, and reads roles in bulk

Performancekamo-shared-library
সারি
২৩ সেপ্টেম্বর, ২০২৬ এ ২:৩৯ PM UTC
লেখক
Kamo
মন্তব্য@ info: status
c4924af

Two related fixes to MemberRightsAppliedService, both in the same file: 1. **************** (via recalcChunk) and **************** unconditionally deleted and re-inserted every one of a member's applied-rights rows, every time they ran. SecurityService's MemberRightsBackfillService calls the org-wide path for EVERY org on EVERY pod boot (a self-heal, by design — see its own javadoc), and the recompute is idempotent: a steady-state boot re-derives the identical set. Measured in production pg_stat_statements: ~12.7M INSERTs against a ~30K-row table — roughly 300 full-table rewrites, one per boot, almost all of them writing back exactly what was already there. Both methods now diff the freshly-computed set against what member_rights_applied already holds (one bulk read for a whole chunk) and only clear + rewrite the members whose rights actually differ. A no-op boot now costs one read and zero writes. 2. calculateMemberRights (the core of both the write path above and the read-only computeMemberRights SessionRefreshController polls on every session refresh) walked member.getRoles(), **************** job-title roles()/getRights() and member.getRights() as separate lazy collections — plus one further lazy load per distinct role, for that role's own rights. Unbounded per member. Six new optional repository fields (MemberRoleRepository, DepartmentRoleRepository, DepartmentRightRepository, JobTitleRoleRepository, JobTitleRightRepository, MemberRightRepository — the first and last already existed) replace those lazy loads with a fixed, small number of bulk queries, each with a role's own rights JOIN-FETCHed. Deliberately NOT an @EntityGraph rooted at Member/TeamMember: both are @Inheritance(JOINED), and an entity graph that fetches further associations off a JOINED entity is the exact shape that took /leads down in production on Hibernate 6.2.13 (missing FROM-clause entry for the root table — see LeadAssigneeRef). Each new repository is instead rooted at the CHILD entity (none of which carry @Inheritance) and filtered by the parent's id. An EntityManager field with @PersistenceContext was tried first and reverted: it is processed by Spring's JPA-aware post-processor whenever spring-orm is on the classpath, so a manually-new'd service in a context with no EntityManagerFactory bean (SignInReadRetryTest's hand-rolled Spring context, which exercises @RetryOnDbConflict through a real AOP proxy) failed BEAN CREATION outright. The optional-repository fields degrade the same way appliedModelResolver already did: @Autowired(required = false) leaves them null with no bean of that type, and the six helpers fall back to the original lazy-load path, unchanged, in every existing test. SessionRefreshController keeps computing live (not from the persisted snapshot) — that endpoint's whole point is "what is true right now", which is explicitly not always what was last persisted.

সব পরিবর্তন

যেমন তুমি জাহাজ দেখেছ?

সব কিছু তোমার নিজের কাজে এসেছে. বিনামূল্যে পরিকল্পনা চালু করুন এবং মাসে পুনরায় এই পাতাটি পড়ুন।.

চিরকালের জন্য মুক্তকরণ আরম্ভ করা হবেপ্রদর্শন সংক্রান্ত পছন্দ