-
Notifications
You must be signed in to change notification settings - Fork 11
chore: init kafka ts consumer #663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
79dd759
cad41a8
e4d3c4e
53901b5
28de25c
d280193
03eff56
f774590
76beef1
5e036c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| name: Apps / Event Queue | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: ["*"] | ||
| paths: | ||
| - apps/event-queue/** | ||
| - packages/logger/** | ||
| - packages/events/** | ||
| - .github/workflows/apps-event-queue.yaml | ||
| - pnpm-lock.yaml | ||
| push: | ||
| branches: ["main"] | ||
| paths: | ||
| - apps/event-queue/** | ||
| - packages/logger/** | ||
| - packages/events/** | ||
| - .github/workflows/apps-event-queue.yaml | ||
| - pnpm-lock.yaml | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
|
|
||
| strategy: | ||
| matrix: | ||
| platform: [linux/amd64] | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up QEMU | ||
| uses: docker/setup-qemu-action@v3 | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - name: Check if Docker Hub secrets are available | ||
| run: | | ||
| if [ -z "${{ secrets.DOCKERHUB_USERNAME }}" ] || [ -z "${{ secrets.DOCKERHUB_TOKEN }}" ]; then | ||
| echo "DOCKERHUB_LOGIN=false" >> $GITHUB_ENV | ||
| else | ||
| echo "DOCKERHUB_LOGIN=true" >> $GITHUB_ENV | ||
| fi | ||
|
|
||
| - name: Login to Docker Hub | ||
| uses: docker/login-action@v3 | ||
| if: env.DOCKERHUB_LOGIN == 'true' | ||
| with: | ||
| username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
| password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
|
||
| - name: Extract metadata (tags, labels) for Docker | ||
| id: meta | ||
| uses: docker/metadata-action@v5 | ||
| with: | ||
| images: ctrlplane/event-queue | ||
| tags: | | ||
| type=sha,format=short,prefix= | ||
|
|
||
| - name: Build | ||
| uses: docker/build-push-action@v6 | ||
| if: github.ref != 'refs/heads/main' | ||
| with: | ||
| push: false | ||
| file: apps/event-queue/Dockerfile | ||
| platforms: ${{ matrix.platform }} | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
|
|
||
| - name: Build and Push | ||
| uses: docker/build-push-action@v6 | ||
| if: github.ref == 'refs/heads/main' && env.DOCKERHUB_LOGIN == 'true' | ||
| with: | ||
| push: true | ||
| file: apps/event-queue/Dockerfile | ||
| platforms: ${{ matrix.platform }} | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,55 @@ | ||||||
| # https://github.com/WhiskeySockets/Baileys/issues/1003#issuecomment-2306467419 | ||||||
| ARG NODE_VERSION=20 | ||||||
| FROM node:${NODE_VERSION}-alpine | ||||||
|
|
||||||
| RUN apk add --no-cache libc6-compat python3 make g++ curl | ||||||
|
|
||||||
| ENV PNPM_HOME="/pnpm" | ||||||
| ENV PATH="$PNPM_HOME:$PATH" | ||||||
|
|
||||||
| RUN npm install -g turbo | ||||||
| RUN npm install -g corepack@latest | ||||||
| RUN corepack enable pnpm | ||||||
|
|
||||||
| WORKDIR /app | ||||||
|
|
||||||
| COPY .gitignore .gitignore | ||||||
| COPY turbo.json turbo.json | ||||||
| RUN pnpm add -g turbo | ||||||
|
|
||||||
| COPY package.json package.json | ||||||
| COPY .npmrc .npmrc | ||||||
| COPY pnpm-*.yaml . | ||||||
|
|
||||||
|
Comment on lines
+20
to
+23
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Do not bake .npmrc into the image; mount it as a BuildKit secret during install Copying -COPY .npmrc .npmrc
@@
-RUN pnpm install --frozen-lockfile
+RUN --mount=type=secret,id=npmrc,dst=/root/.npmrc pnpm install --frozen-lockfileFollow-up (workflow): pass the secret to docker/build-push-action (see my workflow comment adding Also applies to: 33-33 |
||||||
| COPY tooling/prettier/package.json ./tooling/prettier/package.json | ||||||
| COPY tooling/eslint/package.json ./tooling/eslint/package.json | ||||||
| COPY tooling/typescript/package.json ./tooling/typescript/package.json | ||||||
|
|
||||||
| COPY packages/logger/package.json ./packages/logger/package.json | ||||||
| COPY packages/events/package.json ./packages/events/package.json | ||||||
| COPY packages/secrets/package.json ./packages/secrets/package.json | ||||||
| COPY packages/validators/package.json ./packages/validators/package.json | ||||||
| COPY packages/db/package.json ./packages/db/package.json | ||||||
| COPY packages/job-dispatch/package.json ./packages/job-dispatch/package.json | ||||||
| COPY packages/rule-engine/package.json ./packages/rule-engine/package.json | ||||||
|
|
||||||
| COPY apps/event-queue/package.json ./apps/event-queue/package.json | ||||||
|
|
||||||
| RUN pnpm install --frozen-lockfile | ||||||
|
|
||||||
| COPY . . | ||||||
|
|
||||||
| RUN turbo build --filter=...@ctrlplane/event-queue | ||||||
|
|
||||||
| RUN addgroup --system --gid 1001 nodejs | ||||||
| RUN adduser --system --uid 1001 nodejs | ||||||
| USER nodejs | ||||||
|
|
||||||
|
Comment on lines
+44
to
+47
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix Alpine adduser/addgroup flags; current build will fail BusyBox on Alpine does not support the long options -RUN addgroup --system --gid 1001 nodejs
-RUN adduser --system --uid 1001 nodejs
-USER nodejs
+RUN addgroup -S -g 1001 nodejs \
+ && adduser -S -G nodejs -u 1001 nodejs \
+ && chown -R 1001:1001 /app
+USER nodejs🤖 Prompt for AI Agents |
||||||
| ENV NODE_ENV=production | ||||||
| ENV NODE_MAX_OLD_SPACE_SIZE=4096 | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion NODE_MAX_OLD_SPACE_SIZE has no effect; use NODE_OPTIONS. Node reads memory flags from NODE_OPTIONS or CLI args. The current env var won’t change heap size. Apply: -ENV NODE_MAX_OLD_SPACE_SIZE=4096
+ENV NODE_OPTIONS="--max-old-space-size=4096"📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| EXPOSE 3123 | ||||||
|
|
||||||
| WORKDIR apps/event-queue/dist/ | ||||||
|
|
||||||
| CMD ["node", "index.js"] | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Event Queue | ||
|
|
||
| This is a simple event queue that listens to the `ctrlplane-events` topic and logs the events to the console. | ||
|
|
||
| ## Running | ||
|
|
||
| ```bash | ||
| pnpm dev | ||
| ``` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| import baseConfig, { requireJsSuffix } from "@ctrlplane/eslint-config/base"; | ||
|
|
||
| /** @type {import('typescript-eslint').Config} */ | ||
| export default [ | ||
| { ignores: [".nitro/**", ".output/**", "dist/**"] }, | ||
| ...requireJsSuffix, | ||
| ...baseConfig, | ||
| ]; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| { | ||
| "name": "@ctrlplane/event-queue", | ||
| "private": true, | ||
| "type": "module", | ||
| "scripts": { | ||
| "clean": "rm -rf .turbo node_modules", | ||
| "dev": "pnpm with-env tsx watch --clear-screen=false src/index.ts", | ||
| "lint": "eslint", | ||
| "build": "tsc", | ||
| "format": "prettier --check . --ignore-path ../../.gitignore", | ||
| "typecheck": "tsc --noEmit", | ||
| "with-env": "dotenv -e ../../.env --" | ||
| }, | ||
adityachoudhari26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "dependencies": { | ||
| "@ctrlplane/events": "workspace:*", | ||
| "@ctrlplane/logger": "workspace:*", | ||
| "@t3-oss/env-core": "catalog:", | ||
| "dotenv": "^16.4.5", | ||
| "kafkajs": "^2.2.4", | ||
| "zod": "catalog:" | ||
| }, | ||
| "devDependencies": { | ||
| "@ctrlplane/eslint-config": "workspace:^", | ||
| "@ctrlplane/prettier-config": "workspace:^", | ||
| "@ctrlplane/tsconfig": "workspace:*", | ||
| "@types/node": "catalog:node22", | ||
| "eslint": "catalog:", | ||
| "prettier": "catalog:", | ||
| "tsx": "catalog:", | ||
| "typescript": "catalog:" | ||
| }, | ||
| "prettier": "@ctrlplane/prettier-config" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import { createEnv } from "@t3-oss/env-core"; | ||
| import dotenv from "dotenv"; | ||
| import { z } from "zod"; | ||
|
|
||
| dotenv.config(); | ||
|
|
||
| export const env = createEnv({ | ||
| server: { | ||
| NODE_ENV: z | ||
| .enum(["development", "production", "test"]) | ||
| .default("development"), | ||
| KAFKA_BROKERS: z | ||
| .string() | ||
| .default("localhost:9092") | ||
| .transform((val) => | ||
| val | ||
| .split(",") | ||
| .map((s) => s.trim()) | ||
| .filter(Boolean), | ||
| ) | ||
| .refine((arr) => arr.length > 0, { | ||
| message: "KAFKA_BROKERS must be a non-empty list of brokers", | ||
| }), | ||
| }, | ||
| runtimeEnv: process.env, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import { Kafka } from "kafkajs"; | ||
|
|
||
| import { logger } from "@ctrlplane/logger"; | ||
|
|
||
| import { env } from "./config.js"; | ||
adityachoudhari26 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const kafka = new Kafka({ | ||
| clientId: "ctrlplane-events", | ||
| brokers: env.KAFKA_BROKERS, | ||
| }); | ||
|
|
||
| const consumer = kafka.consumer({ groupId: "ctrlplane-events" }); | ||
|
|
||
| export const start = async () => { | ||
| logger.info("Starting event queue", { brokers: env.KAFKA_BROKERS }); | ||
| await consumer.connect(); | ||
| await consumer.subscribe({ topic: "ctrlplane-events", fromBeginning: true }); | ||
| logger.info("Subscribed to ctrlplane-events topic"); | ||
|
|
||
| await consumer.run({ | ||
| eachMessage: async ({ topic, partition, message }) => { | ||
| logger.info("Received event", { | ||
| topic, | ||
| partition, | ||
| message: message.value?.toString() ?? "No message", | ||
| }); | ||
|
|
||
| return Promise.resolve(); | ||
| }, | ||
| }); | ||
| }; | ||
|
|
||
| start(); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| { | ||
| "extends": "@ctrlplane/tsconfig/base.json", | ||
| "compilerOptions": { | ||
| "target": "ESNext", | ||
| "outDir": "dist", | ||
| "noEmit": false, | ||
| "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json", | ||
| "baseUrl": ".", | ||
| "esModuleInterop": true, | ||
| "importsNotUsedAsValues": "remove" | ||
| }, | ||
| "include": ["src", "*.ts"], | ||
| "exclude": ["node_modules"] | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.