Support per app events
This commit is contained in:
parent
ae342910c2
commit
b093b18e6a
|
@ -1,6 +1,7 @@
|
||||||
import { Event } from "@budibase/types"
|
import { Event } from "@budibase/types"
|
||||||
import { CacheKeys, TTL } from "../../../cache/generic"
|
import { CacheKeys, TTL } from "../../../cache/generic"
|
||||||
import * as cache from "../../../cache/generic"
|
import * as cache from "../../../cache/generic"
|
||||||
|
import * as context from "../../../context"
|
||||||
|
|
||||||
type RateLimitedEvent =
|
type RateLimitedEvent =
|
||||||
| Event.SERVED_BUILDER
|
| Event.SERVED_BUILDER
|
||||||
|
@ -15,6 +16,10 @@ const isRateLimited = (event: Event): event is RateLimitedEvent => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isPerApp = (event: RateLimitedEvent) => {
|
||||||
|
return event === Event.SERVED_APP_PREVIEW || event === Event.SERVED_APP
|
||||||
|
}
|
||||||
|
|
||||||
interface EventProperties {
|
interface EventProperties {
|
||||||
timestamp: number
|
timestamp: number
|
||||||
}
|
}
|
||||||
|
@ -69,7 +74,11 @@ export const limited = async (event: Event): Promise<boolean> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventKey = (event: RateLimitedEvent) => {
|
const eventKey = (event: RateLimitedEvent) => {
|
||||||
return `${CacheKeys.EVENTS_RATE_LIMIT}:${event}`
|
let key = `${CacheKeys.EVENTS_RATE_LIMIT}:${event}`
|
||||||
|
if (isPerApp(event)) {
|
||||||
|
key = key + context.getAppId()
|
||||||
|
}
|
||||||
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
const readEvent = async (event: RateLimitedEvent) => {
|
const readEvent = async (event: RateLimitedEvent) => {
|
||||||
|
@ -81,8 +90,7 @@ const recordEvent = async (
|
||||||
event: RateLimitedEvent,
|
event: RateLimitedEvent,
|
||||||
properties: EventProperties
|
properties: EventProperties
|
||||||
) => {
|
) => {
|
||||||
const key = `${CacheKeys.EVENTS_RATE_LIMIT}:${event}`
|
const key = eventKey(event)
|
||||||
|
|
||||||
const limit = RATE_LIMITS[event]
|
const limit = RATE_LIMITS[event]
|
||||||
let ttl
|
let ttl
|
||||||
switch (limit) {
|
switch (limit) {
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
import "../../../../../tests/utilities/TestConfiguration"
|
||||||
import PosthogProcessor from "../PosthogProcessor"
|
import PosthogProcessor from "../PosthogProcessor"
|
||||||
import { Event, IdentityType, Hosting } from "@budibase/types"
|
import { Event, IdentityType, Hosting } from "@budibase/types"
|
||||||
const tk = require("timekeeper")
|
const tk = require("timekeeper")
|
||||||
import * as Cache from "../../../../cache/generic"
|
import * as cache from "../../../../cache/generic"
|
||||||
|
import { CacheKeys } from "../../../../cache/generic"
|
||||||
|
import * as context from "../../../../context"
|
||||||
|
|
||||||
const newIdentity = () => {
|
const newIdentity = () => {
|
||||||
return {
|
return {
|
||||||
|
@ -13,8 +16,11 @@ const newIdentity = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("PosthogProcessor", () => {
|
describe("PosthogProcessor", () => {
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
|
await cache.bustCache(
|
||||||
|
`${CacheKeys.EVENTS_RATE_LIMIT}:${Event.SERVED_BUILDER}`
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("processEvent", () => {
|
describe("processEvent", () => {
|
||||||
|
@ -71,7 +77,7 @@ describe("PosthogProcessor", () => {
|
||||||
tk.freeze(new Date(2022, 0, 3, 6, 0))
|
tk.freeze(new Date(2022, 0, 3, 6, 0))
|
||||||
await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
|
await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
|
||||||
|
|
||||||
expect(processor.posthog.capture).toHaveBeenCalledTimes(4)
|
expect(processor.posthog.capture).toHaveBeenCalledTimes(3)
|
||||||
})
|
})
|
||||||
|
|
||||||
it("sends event again after cache expires", async () => {
|
it("sends event again after cache expires", async () => {
|
||||||
|
@ -82,8 +88,8 @@ describe("PosthogProcessor", () => {
|
||||||
tk.freeze(new Date(2022, 0, 1, 14, 0))
|
tk.freeze(new Date(2022, 0, 1, 14, 0))
|
||||||
await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
|
await processor.processEvent(Event.SERVED_BUILDER, identity, properties)
|
||||||
|
|
||||||
await Cache.bustCache(
|
await cache.bustCache(
|
||||||
`${Cache.CacheKeys.EVENTS_RATE_LIMIT}:${Event.SERVED_BUILDER}`
|
`${CacheKeys.EVENTS_RATE_LIMIT}:${Event.SERVED_BUILDER}`
|
||||||
)
|
)
|
||||||
|
|
||||||
tk.freeze(new Date(2022, 0, 1, 14, 0))
|
tk.freeze(new Date(2022, 0, 1, 14, 0))
|
||||||
|
@ -91,6 +97,49 @@ describe("PosthogProcessor", () => {
|
||||||
|
|
||||||
expect(processor.posthog.capture).toHaveBeenCalledTimes(2)
|
expect(processor.posthog.capture).toHaveBeenCalledTimes(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("sends per app events once per day per app", async () => {
|
||||||
|
const processor = new PosthogProcessor("test")
|
||||||
|
const identity = newIdentity()
|
||||||
|
const properties = {}
|
||||||
|
|
||||||
|
const runAppEvents = async (appId: string) => {
|
||||||
|
await context.doInAppContext(appId, async () => {
|
||||||
|
tk.freeze(new Date(2022, 0, 1, 14, 0))
|
||||||
|
await processor.processEvent(Event.SERVED_APP, identity, properties)
|
||||||
|
await processor.processEvent(
|
||||||
|
Event.SERVED_APP_PREVIEW,
|
||||||
|
identity,
|
||||||
|
properties
|
||||||
|
)
|
||||||
|
|
||||||
|
// go forward one hour - should be ignored
|
||||||
|
tk.freeze(new Date(2022, 0, 1, 15, 0))
|
||||||
|
await processor.processEvent(Event.SERVED_APP, identity, properties)
|
||||||
|
await processor.processEvent(
|
||||||
|
Event.SERVED_APP_PREVIEW,
|
||||||
|
identity,
|
||||||
|
properties
|
||||||
|
)
|
||||||
|
|
||||||
|
// go forward into next day
|
||||||
|
tk.freeze(new Date(2022, 0, 2, 9, 0))
|
||||||
|
|
||||||
|
await processor.processEvent(Event.SERVED_APP, identity, properties)
|
||||||
|
await processor.processEvent(
|
||||||
|
Event.SERVED_APP_PREVIEW,
|
||||||
|
identity,
|
||||||
|
properties
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await runAppEvents("app_1")
|
||||||
|
expect(processor.posthog.capture).toHaveBeenCalledTimes(4)
|
||||||
|
|
||||||
|
await runAppEvents("app_2")
|
||||||
|
expect(processor.posthog.capture).toHaveBeenCalledTimes(8)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue