Skip to content

Commit c636697

Browse files
authored
RTD Module: Wait on Targeting Cache (#249)
1 parent e99298c commit c636697

2 files changed

Lines changed: 75 additions & 19 deletions

File tree

lib/core/prebid/rtd.ts

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ interface RTDConfig {
6565
targetingFromCache: (config?: RTDConfig) => TargetingData | null;
6666
handleRtd: (reqBidsConfigObj: ReqBidsConfigObj, optableExtraData?: any, mergeFn?: any) => Promise<void | null>;
6767
instance: string;
68+
waitForTargeting: boolean;
6869
}
6970

7071
interface RTDOptions {
@@ -78,6 +79,7 @@ interface RTDOptions {
7879
forceGlobalRouting?: boolean;
7980
mergeStrategy?: MergeStrategy;
8081
instance?: string;
82+
waitForTargeting?: boolean;
8183
}
8284

8385
// Merge strategies for EIDs
@@ -162,22 +164,74 @@ function targetingFromCache(config: RTDConfig = {} as RTDConfig): TargetingData
162164
}
163165

164166
// Get targeting data from cache, if available
165-
function readTargetingData(config: RTDConfig): TargetingData {
167+
async function readTargetingData(config: RTDConfig): Promise<TargetingData> {
166168
const cachedData = targetingFromCache(config);
167-
if (!cachedData) {
168-
config.log("info", "No cached targeting data found");
169-
return {};
169+
170+
// Get auction delay from pbjs config
171+
const delay = (window as any)?.pbjs?.getConfig?.()?.realTimeData?.auctionDelay;
172+
173+
// If waitForTargeting is disabled, cache is not empty, or no delay configured, return immediately
174+
if (!config.waitForTargeting || cachedData || !delay) {
175+
if (!cachedData) {
176+
config.log("info", "No cached targeting data found");
177+
return {};
178+
}
179+
180+
// Validate targeting data structure
181+
if (
182+
!cachedData?.ortb2?.user?.eids ||
183+
(!Array.isArray(cachedData?.ortb2?.user?.eids) && Object.keys(cachedData?.ortb2?.user ?? {}).length > 0)
184+
) {
185+
config.log("info", "No valid targeting data found");
186+
return {};
187+
}
188+
189+
config.log("info", `Found targeting data with ${cachedData.ortb2.user.eids.length} EIDs`);
190+
return cachedData;
170191
}
171192

172-
let targetingData = cachedData;
193+
// Cache is empty and delay is configured - wait for event or timeout
194+
config.log("info", `Waiting for targeting data (max ${delay}ms)`);
195+
196+
const targetingData = await new Promise<TargetingData | null>((resolve) => {
197+
let resolved = false;
198+
199+
const eventHandler = () => {
200+
if (!resolved) {
201+
resolved = true;
202+
config.log("info", "Received optableResolved event");
203+
const data = targetingFromCache(config);
204+
resolve(data);
205+
}
206+
};
207+
208+
const timeoutId = setTimeout(() => {
209+
if (!resolved) {
210+
resolved = true;
211+
config.log("warn", `Auction delay timeout (${delay}ms) - no targeting data available`);
212+
window.removeEventListener("optableResolved", eventHandler);
213+
resolve(null);
214+
}
215+
}, delay);
216+
217+
window.addEventListener("optableResolved", eventHandler, { once: true });
218+
219+
// Clean up timeout if event fires first
220+
window.addEventListener("optableResolved", () => clearTimeout(timeoutId), { once: true });
221+
});
222+
223+
if (!targetingData) {
224+
config.log("info", "No targeting data available after waiting");
225+
return {};
226+
}
173227

174228
// Validate targeting data structure
175229
if (!targetingData?.ortb2?.user?.eids || !Array.isArray(targetingData?.ortb2?.user?.eids)) {
176230
config.log("info", "No valid targeting data found");
177231
return {};
178232
}
179233

180-
config.log("info", `Found targeting data with ${targetingData.ortb2.user.eids.length} EIDs`);
234+
config.log("info", `Found targeting data with ${targetingData.ortb2.user.eids.length} EIDs after waiting`);
181235
return targetingData;
182236
}
183237

@@ -332,8 +386,9 @@ function buildRTD(options: RTDOptions = {}): RTDConfig {
332386
appendNewMergeStrategy,
333387
targetingFromCache,
334388
instance: options.instance ?? "instance",
389+
waitForTargeting: options.waitForTargeting ?? false,
335390
async handleRtd(reqBidsConfigObj: ReqBidsConfigObj, optableExtraData?: any, mergeFn?: any): Promise<void | null> {
336-
const targetingData = options.targetingData ?? readTargetingData(this);
391+
const targetingData = options.targetingData ?? (await readTargetingData(this));
337392
try {
338393
return handleRtd(this, reqBidsConfigObj, targetingData, optableExtraData, mergeFn);
339394
} catch (error) {

package-lock.json

Lines changed: 13 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)