Readit News logoReadit News
atul-jalan commented on Show HN: Nicely designed editor for mockups and screenshots   postspark.app... · Posted by u/world1dan
atul-jalan · 5 months ago
Looks interesting. Don't see any info on pricing though?
atul-jalan commented on Show HN: Compose – Build internal tools faster, without leaving your codebase   github.com/compose-dev/co... · Posted by u/atul-jalan
atul-jalan · 5 months ago
Hey HN! I’m Atul, and today I’m super excited to open-source Compose: a server-side SDK for building internal tools faster, without leaving your codebase.

I first showed Compose to HN about 6 months ago (https://news.ycombinator.com/item?id=41722189).

Back then, I was really interested in the idea of Retool, but with code. Retool proved that you can save a bunch of time by giving people high-level primitives to build internal tools. What if there was something that gave you all the same primitives and conveniences of a hosted platform, but packaged inside an SDK that let you build in your own IDE and benefitted from the power of code.

Since then, I’ve talked to a lot of developers and developed Compose into a platform that actual startups are using!

Basically, Compose has two parts:

- Build internal tools in your backend using our SDKs for Python and TypeScript.

- Use/share those tools via your Compose web dashboard.

The Compose SDK includes primitives like tables, forms, charts, file uploads, and a bunch more to build useful tools in just a few lines of code. Since the SDK is installed into your backend, connecting these primitives to your own data and logic is as easy as importing functions and calling them within the Compose Apps that you define.

The Compose web dashboard renders UIs for your tools and enables you to share them with your entire team. It also includes audit logs, RBAC, and other useful features to manage your tools without any configuration on your end.

Under the hood, the web dashboard maintains a secure, proxied websocket connection to the Compose SDK to run the tools you build.

Here’s a super basic Node.js example that lets you turn a SQL query into a simple table dashboard (there’s also a python SDK).

  import { Compose } from "@composehq/sdk";

  import { database } from "../database";

  const viewUsersApp = new Compose.App({
    route: "view-users",
    handler: async ({ page, ui }) => {
        const users = await database.selectUsers() // query your database
        page.add(() => ui.header(`Total: ${users.length} users`)
        page.add(() => ui.table("users-table", users)); // display results in a table
    }
  })
Please let me know what you think!

Website: https://composehq.com

Docs: https://docs.composehq.com

Code: https://github.com/compose-dev/compose

atul-jalan commented on The hidden complexity of scaling WebSockets   composehq.com/blog/scalin... · Posted by u/atul-jalan
Sytten · 7 months ago
The comment about Render/Railway gracefully tranferring connections seems weird? I am pretty sure it just kills the service after the new one is alive which will kill the connections. Not some fancy zero downtime reconnect.
atul-jalan · 7 months ago
It does, but it will generally give a grace period for outstanding requests to resolve prior to killing the service.

It's a good idea for short-lived HTTP requests, but will cause problems for a persistent connection.

atul-jalan commented on The hidden complexity of scaling WebSockets   composehq.com/blog/scalin... · Posted by u/atul-jalan
tbarbugli · 7 months ago
> At Compose, every WebSocket message starts with a fixed 2-byte type prefix for categorizing messages.

some of the complexity is self-inflected by ignoring KISS principle

atul-jalan · 7 months ago
How would you make it simpler?
atul-jalan commented on The hidden complexity of scaling WebSockets   composehq.com/blog/scalin... · Posted by u/atul-jalan
dilyevsky · 7 months ago
> WebSocket connections can be unexpectedly blocked, especially on restrictive public networks.

What? How would public network even know you’re running a websocket if you’re using TLS? I dont think it’s really possible in general case

> Since SSE is HTTP-based, it's much less likely to be blocked, providing a reliable alternative in restricted environments.

And websockets are not http-based?

What article describes as challenges seems like very pedestrian things that any rpc-based backend needs to solve.

The real reason websockets are hard to scale is because they pin state to a particular backend replica so if the whole bunch of them disconnect at scale the system might run out of resources trying to re-load all that state

atul-jalan · 7 months ago
The initial handshake will usually include an `Upgrade: websocket` header, which can be inspected by networks.
atul-jalan commented on The hidden complexity of scaling WebSockets   composehq.com/blog/scalin... · Posted by u/atul-jalan
hombre_fatal · 7 months ago
I've done my share of building websocket servers from scratch, but when you don't use libraries like ActiveCable or socket.io, you have to build your own MessageID reconciliation so that you can have request/response cycles. Which is generally what you want (or eventually want) in a websocket-heavy application.

    send(payload).then(reply => ...)

atul-jalan · 7 months ago
Yep, for our application, we have an `executionId` that is sent in essentially every single WebSocket message.

But client and server use it to maintain a record of events.

atul-jalan commented on The hidden complexity of scaling WebSockets   composehq.com/blog/scalin... · Posted by u/atul-jalan
exabrial · 7 months ago
I recall another complication with websockets: IIRC it's with proxy load balancers, like binding a connection to a single connection server, even if the backend connection is using HTTP/2. I probably have the details wrong. I'm sure someone will correct my statement.
atul-jalan · 7 months ago
I think there is a way to do it, but it likely involves custom headers on the initial connection that the load balancer can read to route to the correct origin server.

I imagine the way it might go is that the client would first send an HTTP request to an endpoint that returns routing instructions, and then use that in the custom headers it sends when initiating the WebSocket connection.

Haven't tried this myself though.

u/atul-jalan

KarmaCake day98August 26, 2024View Original