Preface of something that barely exists, as everything is a simulation, innit?
I should grab your attention with the best and most sophisticated words created by top-notch AI; nevertheless, I hope you if you exist prefer more organic and crafted posts (considering the numerous posts produced directly from the dark forest). Yeah, I also know about the thrive in obscurity and sometimes I find myself reflecting on the future and how it might be gazing into the abyss without anyone caring about what I do. I'm trying to push myself out and shout to an audience that might not even exist. Moreover, I should probably be sleeping instead of writing this down, hehe
Back from the reverie, let's talk about re-architect something
Recently, I was refactoring a cron job that ran every hour, every day, to obtain lab results from a laboratory provider that lacked a webhook to notify us when a laboratory checkup result was ready. So the outsourcing engineers from the beginning era created a bloater, basically a HUGE lambda with 10 gigs of memory and 15-minute timeout in a x86 architecture, to process all the appointments and try to find a lab result, as this was made without caring about the scale that this has now.
Consequence:
The lambda hourly times out without processing the entire appointment list, and most of the time repeats from the beginning of the list without any "bookmarks" ðŸ˜
911, 911, in case of fire, 911 (read it in pinkfong rythm)
Event Scheduler for the rescue!
Amazon EventBridge Scheduler is a serverless scheduler that allows you to create, run, and manage tasks from one central, managed service
I had the idea to use a simple and powerful solution. Whenever we create a service request successfully, we can schedule an event to get this result based on the exam SLA, so the simplified example of the architecture is the following
Creating the rule for the lab result scheduler:
const schedulerRule = new Rule(this, `${fnPrefix}-scheduler-rule`, {
eventPattern: {
source: ['event.labResultScheduler'],
detailType: ['labName'],
},
})
schedulerRule.addTarget(new LambdaFunction(labResultSchedulerFn))
Aight, so basically, for your Lambda to get triggered by AWS Scheduler, you gotta hook it up with some legit permissions.
First off, that iam:PassRole
thingy is like, super crucial, it lets your Lambda basically "pass on" its role to another AWS service, in this case, the Scheduler. Without it, Scheduler can't tell your Lambda, "Yo, run this function with your permissions!" And then, that lambda:InvokeFunction
permission? That's just straight-up saying, "Scheduler, you're cleared to call my Lambda.
"Think of it like giving your friend the keys to your car (PassRole
) and then telling them, "Yeah, you can drive it too" (InvokeFunction
), no cap, let's code:
Giving the car's keys to your loyal friend
lambda.addToRolePolicy(
new PolicyStatement({
effect: Effect.ALLOW,
actions: ['iam:PassRole'],
resources: ['*'],
}),
)
lambda.addPermission('AllowSchedulerInvoke', {
principal: new ServicePrincipal('scheduler.amazonaws.com'),
action: 'lambda:InvokeFunction',
sourceArn: `arn:aws:scheduler:${this.resourcesStack.config.region}:${this.resourcesStack.config.account}:schedule/*`,
})
The event bridge publisher client:
import { EventBridgeClient, PutEventsCommand } from '@aws-sdk/client-eventbridge'
export type EventBridgePublisherProps = {
source: string
detailType: string
eventBusName: string
detail: Record<string, any>
}
export class EventBridgePublisher {
private client: EventBridgeClient
constructor() {
this.client = new EventBridgeClient()
}
public async publish(event: EventBridgePublisherProps): Promise<void> {
const command = new PutEventsCommand({
Entries: [
{
Source: event.source,
DetailType: event.detailType,
EventBusName: event.eventBusName,
Detail: JSON.stringify(event.detail),
},
],
})
await this.client.send(command)
}
}
Publishing the event:
const customEvent = {
source: 'event.labResultScheduler',
detailType: targetFn,
eventBusName: 'default',
detail: {
target,
entity: 'labResults',
entityId: externalOrderId,
version: '1.0',
eventTime: new Date().toISOString(),
},
}
this.eventBridgePublisher.publish(customEvent)
Adding permission to produce events in your Lambda should follow:
lambda.addToRolePolicy(
new PolicyStatement({
effect: Effect.ALLOW,
actions: ['events:PutEvents', 'scheduler:*'],
resources: ['*'],
}),
)
The policy above it's too permissive, and I know this was just to figure out how to do it xD
Conclusion
Sleep well, drink water, refactor all bloaters if you can, think out of the box and always believe in serveless.
Top comments (0)