Configurable maximum batch size. Connector batches exceeding this are truncated.
ReadonlyMaxEffective per-table column limit — read from MJ_INTEGRATION_MAX_COLUMNS_PER_TABLE at startup and clamped to [1, MAX_COLUMNS_CEILING] (defaults to the ceiling when unset). Objects whose column count exceeds this are auto-disabled at apply time (reversible) instead of failing CREATE TABLE.
Static ReadonlyMAX_SQL Server's hard per-table column limit is 1024; the framework reserves headroom for its own sync/system columns (the _mj_integration* set + ID + timestamps), so the effective ceiling is 1000. MJ_INTEGRATION_MAX_COLUMNS_PER_TABLE can only LOWER this, never raise it past 1000.
Static ReadonlyRECORD_Hard ceiling on the record-map keyset page size. Each page is one round trip that materializes this many rows in memory; past 50k the per-page cost stops amortizing and starts risking the response-size limits of the transport.
Static ReadonlyRecordPage size for the keyset walk over MJ: Company Integration Record Maps (see LoadAllRecordMaps). Read from MJ_INTEGRATION_RECORD_MAP_PAGE_SIZE at class-init and clamped to [1, RECORD_MAP_PAGE_SIZE_CEILING]; defaults to 10,000.
ProtectedBaseProtectedProviderReturns the active provider — the current run's own provider when inside a run, otherwise the global default.
StaticInstanceConfigures the engine by loading all integration metadata. Delegates to IntegrationEngineBase.Config().
OptionalforceRefresh: booleanOptionalcontextUser: UserInfoOptionalprovider: IMetadataProviderWorker-mode enqueue (PR 1 item 8): create the run row with Status='Queued' and
return its ID immediately, without executing anything. A worker process picks it up
via ExecuteQueuedRun; the claim sproc provides the mutual exclusion, so any
number of workers can poll the same queue safely.
The trigger type and sync options are persisted on the run's ConfigData so the
worker executes exactly what the caller asked for, in a different process.
Optionaloptions: IntegrationSyncOptionsOptionalprovider: IMetadataProviderWorker-mode execution (PR 1 item 8): take a Queued run row, claim it, and execute
it in THIS process. Returns a failed result (without side effects) when the run is
no longer queued or when another worker won the claim — losing the race is normal
and must never be treated as an error condition by the caller's poll loop.
Optionalprovider: IMetadataProviderThe Global Object Store is a place to store global objects that need to be shared across the application. Depending on the execution environment, this could be the window object in a browser, or the global object in a node environment, or something else in other contexts. The key here is that in some cases static variables are not truly shared because it is possible that a given class might have copies of its code in multiple paths in a deployed application. This approach ensures that no matter how many code copies might exist, there is only one instance of the object in question by using the Global Object Store.
Source field names the connector declared as SyncDirective 'Exclude' for one integration object, read from IntegrationObjectField.Configuration. Empty set on any lookup miss (unknown object, no fields, no integration id) - a failed lookup must never widen or narrow the sync beyond its declared behaviour.
Resumes any syncs that were orphaned by a process restart. Finds all CompanyIntegrationRun records with Status='In Progress', determines which entity maps already completed (have run details), and resumes from the remaining entity maps using existing watermarks.
Call this once during MJAPI startup after metadata is loaded.
Optionalprovider: IMetadataProviderExecutes a full sync run for a company integration. If a sync is already running for the same integration, waits for it to finish and returns the existing result (concurrency lock).
ID of the CompanyIntegration to sync
User context for all data operations
What triggered this sync (defaults to 'Manual')
OptionalonProgress: OnProgressCallbackOptional callback invoked with progress updates during sync
OptionalonNotification: OnNotificationCallbackOptional callback invoked with a notification when the sync completes or fails
Optionaloptions: IntegrationSyncOptionsOptionalprovider: IMetadataProviderAggregate sync result with record counts and errors
Registers (or clears, with undefined) the post-sync custom-column promotion hook.
StaticAcquireAcquires the maintenance lock for a CompanyIntegration. Returns false (does NOT wait) when
a data sync is currently running or another maintenance operation already holds the lock —
the caller decides whether to wait for GetSyncProgress to clear or surface the conflict.
StaticCancelSuperseded by IntegrationEngine.CancelSyncAsync, which records the cancel on the run row so the owning process observes it at its next batch boundary.
Retained with its original signature for published consumers. Returns false —
truthfully reporting that it cancelled nothing — rather than pretending to succeed,
so a caller branching on the result is not silently misled.
StaticCancelRequest cancellation of a running (or queued) sync by stamping CancelRequestedAt on the live run row (PR 1 item 4 — the DATABASE is the single source of cancellation truth, so a cancel issued in ANY process reaches the owner). The owner observes the stamp at its next batch boundary / lease renewal and stops after the current batch. Returns true when a live run row was stamped.
Optionalprovider: IMetadataProviderStaticClassifyClassifies a fetched batch against the ctx.BatchSize the engine asked for. Returns null when
the batch is within contract, so the caller can treat "no verdict" as "nothing to warn about".
Two severities, because they are different defects:
CONNECTOR_UNBOUNDED_BATCH — the FIRST batch came back over-size AND HasMore is not true,
i.e. the connector ignored pagination entirely and pulled the whole object into memory in one
request. That is what OOMs a large tenant, and it grows silently with the customer's data.CONNECTOR_IGNORED_BATCH_SIZE — the connector IS paging but overshoots the requested size
(e.g. a hardcoded page size). Bounded memory, still a contract violation worth fixing.Public + static because the decision is the interesting part and deserves a unit test that doesn't have to stand up a whole sync (same rationale as RatchetProgressSnapshot).
StaticGetNo direct replacement. Query MJ: Company Integration Runs for rows whose
Status is In Progress or Queued and read their ProgressJSON, which is what
IntegrationEngine.GetSyncProgressAsync does for a single connector.
Retained with its original signature for published consumers; returns an empty map.
Protected StaticgetReturns the singleton instance of the class. If the instance does not exist, it is created and stored in the Global Object Store. If className is provided it will be used as part of the key in the Global Object Store, otherwise the actual class name will be used. NOTE: the class name used by default is the lowest level of the object hierarchy, so if you have a class that extends another class, the lowest level class name will be used.
OptionalclassName: stringStaticGetCurrent maintenance lock for a CompanyIntegration, or undefined when none is held.
StaticGetSuperseded by IntegrationEngine.GetSyncProgressAsync, which reads the run row and therefore sees runs owned by ANY process.
Retained with its original signature so a published consumer does not break on a
minor upgrade. It cannot be made to work: the static map it used to read was removed
when progress moved to the database, and a synchronous method cannot query it. It
returns undefined — the same value it returned when no run was in progress — and
logs once explaining the replacement.
StaticGetRead current sync progress for a connector FROM THE DATABASE (PR 1 item 4 — progress lives on the run row, so it is visible from ANY process, not just the one executing the sync). Returns undefined when no live run exists. A run is "live" when Status is In Progress/Queued AND its lease has not expired — an expired lease means the owner died and the snapshot is stale history, not progress.
Optionalprovider: IMetadataProviderStaticPollWorker-mode poll (PR 1 item 8): the oldest claimable Queued runs. A row is claimable
when it is unowned or its lease has lapsed — a Queued row with a LIVE lease is being
started by another worker right now and must not be returned. This is only a
candidate list; ExecuteQueuedRun's atomic claim is what actually grants
exclusivity, so two workers polling simultaneously is safe by construction.
Optionalprovider: IMetadataProviderStaticRatchetU3 — pure, MONOTONIC progress fold: applies one per-map progress event to the live snapshot as a high-water mark. Under syncConcurrency > 1 events arrive out of order, so counters only ever ratchet UP — a progress bar must never go backwards. Totals are assigned (they're authoritative per event); completed/processed take max().
StaticReleaseReleases the maintenance lock (idempotent — safe in a finally).
Generic, abstract base class for any scenario where we want to use a Singleton pattern. This base class abstracts away the complexity of ensuring a truly global singleton instance across multiple code paths in a deployed application. It uses a Global Object Store to ensure that only one instance of the class exists in the application even if the class has code imported into multiple execution paths (which is not optimal, of course, but can occur in some situations).