Skip to content

mish-tv/distributed-counter

Repository files navigation

@mish-tv/distributed-counter

npm Build and test coverage license

`@mish-tv/distributed-counter is a library for creating distributed counters using CloudDatastore, CloudTasks, and CloudRun.

Installation

npm install --save @mish-tv/distributed-counter

Usage

Preparation

  • Enable Datastore / CloudRun / CloudTasks.
  • Create a Queue with an arbitrary name in CloudTasks. In the following example, you will need a queue named distributed-counter-counter.
  • Create a service account to run CloudRun from CloudTasks. Please refer to this document.

Deploy aggregate server

Deploy a server application to CloudRun. You can use the image I have created.

The deployment to CloudRun is complete, note the URL to request. Apply the URL you have note to the constant named url in the following sample code.

TAG=v1.2.0
REGION=${your_region}
IMAGE=us-east4-docker.pkg.dev/${YOUR_PROJECT_ID}/distributed-counter/aggregate-server:${TAG}

docker pull malt03/aggregate-server:${TAG}
docker tag malt03/aggregate-server:${TAG} ${IMAGE}
docker push ${IMAGE}

gcloud run deploy aggregate-distributed-counter --image ${IMAGE} --platform managed --region ${REGION} --no-allow-unauthenticated

Implementation

import { Datastore } from "@google-cloud/datastore";
import { createIncrementor } from "@mish-tv/distributed-counter";

const datastore = new Datastore();
const projectId = "";
const location = "us-east4";
// const url = `https://aggregate-distributed-counter-${dummy}-uk.a.run.app`;
// const serviceAccount = `cloud-tasks@${projectId}.iam.gserviceaccount.com`;
const increment = createIncrementor(url, serviceAccount, (key, client) =>
  client.queuePath(projectId, location, `distributed-counter-${key.kind}`)
);

export const incrementCounter = async (id: string, value: number) => {
  const key = datastore.key(["counter", id]);
  const initialEntity = { foo: "bar" };
  await increment(key, "value", value, {
    type: "INITIALIZE",
    properties: () => initialEntity,
  });
};