Skip to content

Commit

Permalink
Improve logs component (#264)
Browse files Browse the repository at this point in the history
* small thing so that focus ring doesn't stand out too much

* refactor Layout comp into separate pieces and unify spacing

* add icon with notif

* upgrade logs table and add its initial empty state

* formatting

* add some code to introduce potential concurrency bugs in the goose quotes app

* improve the empty state

* add a copy message to clipboard button

* formatting

* update changelog

* update the workflow to only build when client-library, api or studio are impacted

* simplify the logic

* move styles to tailwind

* inline some of the components
  • Loading branch information
keturiosakys authored Sep 18, 2024
1 parent 21df2af commit 637b577
Show file tree
Hide file tree
Showing 24 changed files with 752 additions and 510 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/build_frontends.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,16 @@ name: Build node packages
on:
pull_request:
branches: ["*"]
paths:
- "api/**"
- "packages/client-library-otel/**"
- "studio/**"
push:
branches: ["main", "release-*"]
paths:
- "api/**"
- "packages/client-library-otel/**"
- "studio/**"

env:
CARGO_TERM_COLOR: always
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE "geese" ADD COLUMN "honks" integer DEFAULT 0;
101 changes: 101 additions & 0 deletions examples/goose-quotes/drizzle/meta/0001_snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{
"id": "d13ec396-5ca3-4ae5-8451-3442765c5abb",
"prevId": "301ac579-5843-4fa3-8b30-6012ab5546da",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.geese": {
"name": "geese",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": false
},
"is_leader": {
"name": "is_leader",
"type": "boolean",
"primaryKey": false,
"notNull": false
},
"programming_language": {
"name": "programming_language",
"type": "text",
"primaryKey": false,
"notNull": false
},
"motivations": {
"name": "motivations",
"type": "jsonb",
"primaryKey": false,
"notNull": false
},
"location": {
"name": "location",
"type": "text",
"primaryKey": false,
"notNull": false
},
"bio": {
"name": "bio",
"type": "text",
"primaryKey": false,
"notNull": false
},
"avatar": {
"name": "avatar",
"type": "text",
"primaryKey": false,
"notNull": false
},
"honks": {
"name": "honks",
"type": "integer",
"primaryKey": false,
"notNull": false,
"default": 0
},
"created_at": {
"name": "created_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"schemas": {},
"sequences": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}
7 changes: 7 additions & 0 deletions examples/goose-quotes/drizzle/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
"when": 1722995764012,
"tag": "0000_talented_the_watchers",
"breakpoints": true
},
{
"idx": 1,
"version": "7",
"when": 1726591286939,
"tag": "0001_last_captain_america",
"breakpoints": true
}
]
}
23 changes: 20 additions & 3 deletions examples/goose-quotes/src/db/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,24 @@ export const updateGoose = async (
updateData: Partial<typeof geese.$inferInsert>,
) => {
console.log({ action: "updateGoose", id, updateData });
return (
await db.update(geese).set(updateData).where(eq(geese.id, id)).returning()
)[0];

// Simulate a race condition by splitting the update into two parts
const updatePromises = Object.entries(updateData).map(
async ([key, value]) => {
// Introduce a random delay to increase the chance of interleaved updates
await new Promise((resolve) => setTimeout(resolve, Math.random() * 1000));

return db
.update(geese)
.set({ [key]: value })
.where(eq(geese.id, id))
.returning();
},
);

// Wait for all updates to complete
const results = await Promise.all(updatePromises);

// Return the last result, which may not contain all updates
return results[results.length - 1][0];
};
2 changes: 2 additions & 0 deletions examples/goose-quotes/src/db/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
boolean,
integer,
jsonb,
pgTable,
serial,
Expand All @@ -17,6 +18,7 @@ export const geese = pgTable("geese", {
location: text("location"),
bio: text("bio"),
avatar: text("avatar"),
honks: integer("honks").default(0),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
});
41 changes: 33 additions & 8 deletions examples/goose-quotes/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,19 @@ app.post("/api/geese/:id/honk", async (c) => {
return c.json({ message: "Goose not found" }, 404);
}

console.log(`Honk received for goose: ${goose.name}`);
return c.json({ message: `Honk honk! ${goose.name} honks back at you!` });
const currentHonks = goose.honks || 0;

const updatedGoose = await measure("updateGoose", () =>
updateGoose(db, +id, { honks: currentHonks + 1 }),
)();

console.log(
`Honk received for goose: ${goose.name}. New honk count: ${updatedGoose.honks}`,
);
return c.json({
message: `Honk honk! ${goose.name} honks back at you!`,
honks: updatedGoose.honks,
});
});

/**
Expand All @@ -302,21 +313,35 @@ app.patch("/api/geese/:id", async (c) => {
const db = drizzle(sql);

const id = c.req.param("id");
const { name } = await c.req.json();
const updateData = await c.req.json();

console.log(`Updating goose ${id} with new name: ${name}`);
console.log(`Updating goose ${id} with data:`, updateData);

const goose = await measure("updateGoose", () =>
updateGoose(db, +id, { name }),
)();
const goose = await measure("getGooseById", () => getGooseById(db, +id))();

if (!goose) {
console.warn(`Goose not found: ${id}`);
return c.json({ message: "Goose not found" }, 404);
}

// Simulate a race condition by splitting the update into multiple parts
const updatePromises = Object.entries(updateData).map(
async ([key, value]) => {
await new Promise((resolve) => setTimeout(resolve, Math.random() * 1000));
return measure("updateGoose", () =>
updateGoose(db, +id, { [key]: value }),
)();
},
);

await Promise.all(updatePromises);

const updatedGoose = await measure("getGooseById", () =>
getGooseById(db, +id),
)();

console.log(`Goose ${id} updated successfully`);
return c.json(goose);
return c.json(updatedGoose);
});

/**
Expand Down
Loading

0 comments on commit 637b577

Please sign in to comment.