HackerLangs
TopNewTrendsCommentsPastAskShowJobs

socketcluster

612 karmajoined 3 वर्ष पहले
Email: jon(at)socketcluster.io

comments

socketcluster
·परसों·discuss
This is neat. I've been dreaming of something like this to host frontends connected to my backend platform https://saasufy.com - I can get Claude Code to create a data-driven app entirely inside an index.html file on my computer's file system, then, because it's built with WebSockets, it doesn't have CORS limitations so I can open it directly from the file system by double-clicking it (served via file:// protocol) then, when I'm happy, I can drag that file and drop it on Cloudflare Drop and then it's deployed online. No text editor/IDE, no server needed in the entire process.
socketcluster
·परसों·discuss
I agree that AI does well when the patterns in the code are predictable and consistent.

That said it can work surprisingly well with custom frameworks and tools provided that they are predictable and consistent.

For example, I created a platform with custom Web Components. Agents do a great job at using the components by reading the docs. I find it a lot easier and more succinct than React. I think it's because AI isn't as good with high level patterns when there are too many pieces involved and too many sub-patterns to apply, it gets so caught up in the details that it misses the forest for the trees.

My SDK abstracts away a lot of low-level complexity so that agents are able to focus on higher-level architectural patterns. Also, it's very succinct so agents can fit a lot of context/functionality into its context window. It gets faster and better as the codebase grows.

Here's the link if anyone wants to try: https://saasufy.com/
socketcluster
·6 दिन पहले·discuss
ORMs are an anti-pattern. What ends up happening on most projects is that, over time, the ORM ends up generating increasingly complex, inefficient SQL queries behind the scenes. Since some of the people who use the ORM don't understand SQL, they don't realize how inefficient their ORM logic is; it looks like a simple operation from their perspective... It's only if you look under the bonet that you realize that the SQL being generated behind the scenes is a monstrosity. Nobody would have dared write this fugly mass of SQL by hand but from the ORM layer, it looks reasonable... Just a few objects joined by dots....
socketcluster
·9 दिन पहले·discuss
That seems to make the case stronger. It becomes Cloudflare's problem. You can deal with Cloudflare from one country and let them figure out how to collect payment from people all over.

That said, morally, I strongly resent the fact that accepting payment has essentially become illegal for most people due to this complexity and the way globalization has been forced on people. People are essentially not allowed to receive payment to feed themselves. That's what it has come down to. Not everyone can afford an accountant and take that risk.
socketcluster
·11 दिन पहले·discuss
I think OOP helps to build loosely coupled systems but it doesn't protect you from tight coupling. You have to know what you're doing.

I think OOP languages made some pragmatic decisions. Sometimes a feature which is harmful 95% of the time could be genuinely useful and safe 5% of the time... Some languages like Haskell might choose to not allow that feature at all and force the developer to find another approach which is almost as effective for that 5% of cases; that's fair enough. It's a different philosophy.

I feel like that about passing mutable objects by reference. I find it harmful most of the time but there are rare cases were it's convenient and beneficial. I've worked on open source projects were I wanted the user to be able to use the software with any database so my function accepted a database adapter as an argument.

I could have achieved a similar goal in another way but I would have had to sacrifice separation of concerns slightly. I wanted the ability to substitute any database but also wanted the component to be responsible for the persistence and recovery of its own state as this was within its responsibilities. Also this was the only violation in the entire codebase so I deemed it acceptable. It didn't pose any problems at all in practice.
socketcluster
·11 दिन पहले·discuss
There are definitely cases where you could have a module with distinct responsibilities; so you can definitely get high cohesion and loose coupling without OOP, that's true, but there are cases where you may want to:

- Control the timing of when a module is activated (instantiated).

- Have multiple instances of a module with variations in functionality where those variations are not a concern to the parent module/instance.

For me, this is when OOP becomes most useful. If I can write some code once and later use it to create any number of independent instances with the same functionality which can clean up after themselves, this is generally a lot more maintainable than having one module to keep track of all the different states in an array and micromanaging (for example) the rendering and cleanup work associated with multiple distinct pieces of state.
socketcluster
·11 दिन पहले·discuss
IMO, the most important philosophy in all of software engineering is "Separation of responsibilities." The best way to achieve it is through the principle of "High cohesion, loose coupling."

OOP is just another layer of philosophy which builds on top of that. It's more specific, imposes additional guardrails. It requires objects with state encapsulation (locality) and message-passing as the mechanism for components to interact with each other; each component is responsible for changing a subset of the state of the system. Each component is responsible for handling messages (calls to action) by performing local state changes and potentially also sending messages to other components which have more specific sub-responsibilities.

OOP without "High cohesion, loose coupling" is almost worthless IMO. It must build on top.

I think were most people fail with OOP is that they think coming up with good separation of concerns, good abstractions is easy. They just start implementing the first idea which comes out of their heads and then figure out the scope of responsibilities as they go.

The test for good separation of concerns is that you should be able to explain your architecture to someone with the intellect of a 9 year old child who happens to understand the business domain. I'm not exaggerating. It has to be that obvious or else you will not be able to maintain clean separation... You will not be able to maintain alignment in your team.

If the responsibilities of a specific object are somewhat vague, what will happen is that the scope of responsibilities between objects will soon blur and the messages between objects will start to look increasingly elaborate; your system will look like a bunch of horrible incompetent managers trying to micromanage junior employees using long, convoluted instructions and occasionally throwing chairs at them...

If your system is passing around object references all over the place; that's usually a sign of poor separation of concerns; passing around complex objects by reference is tight coupling, by definition. Each object, each person should be able to fulfill their responsibilities and finish the job using communication only.
socketcluster
·16 दिन पहले·discuss
It supports attribute-based access control (similar to RLS but more granular) and also Group-based access control for more advanced situations.

Authorization is enforced based on CRUD rules that are defined on the control panel on each Model. For Create, Read, Update or Delete actions, the permission can be either "block" (don't allow anyone to perform this action), "restrict" (only allow if the user has a token which matches the resource) or "allow" (anyone can perform this action on the resource without authentication).

Permissions are enforced at the Collection and row/record level by default but can be overridden on a per-field basis so you could, for example, have a record which could be read by anyone but only the owner can edit a specific field. You could also make it so that a specific set of users is allowed to read a resource but only one of them (or perhaps a third one) is allowed to edit.

When the user authenticates themselves, they are issued a signed JWT token.

From the control panel, you just need to specify which property of the JWT to match against which field of the model; it can be the same for all CRUD actions or different for each one. The token contains an accountId property. You just need to select the corresponding field on the model and the backend middleware will match both values to decide whether or not the 'restrict' condition is met. If the accountId in the token does not match the one on a resource, then the user will be blocked. In 'restrict' mode, if fetching a list based on a filtered view, the user will be blocked if the list/page contains a resource which does not match their accountId from their JWT. The views can be parameterized with an accountId field from the client when applying an indexed filter so you can easily define views which meet the restrict criteria for any given user.

You don't really need to know any of this though because you can just ask your AI to define these rules for you and you can ask it to run tests as it can call all the CRUD actions with HTTP and you can make your AI agent impersonate any accountId you want by associating it with the API credential of your AI agent via the control panel.

You can also enforce group-based access control for handling large dynamic groups but the default attribute-based access control is quite versatile and you can optionally have multiple owners on a resource with comma-separated accountIds but you have to update the resources individually. It's good for simple sharing scenarios where one user wants to transfer ownership of a resource to another user. They could add a second owner and then the second owner could later remove the first owner to gain exclusive ownership.

This approach is also useful for simple private chat scenarios where two users are allowed to read a private message but only the sender is allowed to edit it. You can have different properties on the Model to enforce access for read vs update... For example a field readerAccountIds (Read) and senderAccountId (Update).
socketcluster
·16 दिन पहले·discuss
I've been working on a similar product. Started working on it 14 years ago and pivoted it to vibe coding. https://saasufy.com/

I'm thinking to open source it but I want to see some traction before doing that since I don't want to open source then someone else takes my code and I get nothing out of it.
socketcluster
·23 दिन पहले·discuss
Because security hasn't been a major concern yet... But wait for the AI models to catch up.
socketcluster
·24 दिन पहले·discuss
This is why I built https://saasufy.com/ - Vibe coders shouldn't trust themselves with backend security. Unfortunately, it's extremely difficult to get right. There's a lot to think about;

- Schema validation with appropriate size limits on all relevant fields.

- Authentication.

- Access control.

- Backpressure management and rate limiting in case a (possibly malicious) user tries to perform too many computationally expensive actions in a short time.

- Ensuring that the actions of one user doesn't throttle another user which is connected to the same process/host, e.g. using async constructs to avoid freezing the main process.

- DDoS mitigation.

- Avoiding race conditions.

- Designing a good database schema, with well chosen indexes, with deterministic IDs/idempotency to avoid double-insertion scenarios. You don't want to be forced to rely on overly complex queries with a lot of joins. This doesn't scale well and rarely necessary.

- Logging and error handling.

- Avoiding conflicts and accidental overwrite with old data when multiple users are editing different fields of the same resource concurrently.

- Efficient distribution of realtime messages.

- Scalability.

The list goes on and on... And every piece has to be implemented perfectly. This involves a huge number of carefully thought-out decisions.
socketcluster
·पिछला माह·discuss
Wow the token leaderboard idea is nuts. It's similar to trying to measure the productivity of software engineers based on number of lines of code.
socketcluster
·पिछला माह·discuss
Fully agree. Shipping a complete product with a functioning user acquisition funnel is much harder. It's like; you have to build the whole product first with lots of features and then you have to try to create a highly condensed overview of all those features to expose them all on the landing page.

If you can't make the visitor understand your entire complex product in 10 seconds, then you've lost them.

Your product has to be complex because that's where the software market is at. All of the low-hanging fruits have been taken by the time you identify them. Sure, someone will find a way to make money using new low-hanging fruits that arise due to technological changes but it's not going to be you. You probably don't have the business connections to make that work.
socketcluster
·पिछला माह·discuss
Interesting reading this because this is essentially the principle behind https://socketcluster.io/ scalability; the sharding of channels across available brokers is pseudo-random. It uses a hash function for determinism but the distribution appears to be random and that was also the best way I could find to distribute load evenly between available nodes. It is key to its embarrassingly parallel design.

It's interesting to see it being done at the data centre level as well.
socketcluster
·पिछला माह·discuss
I started building something pretty obscure about 14 years ago; https://socketcluster.io/ an open source, WebSocket-based RPC + pub/sub library with a focus on in-order async stream-processing with backpressure monitoring.

It didn't start out like that. Initially, it was just another WebSocket library with a focus on making it easier to scale to multiple processes.

It's kind of mind-bending to me though that it still feels like it's "too early." You'd think that the ability to efficiently process RPCs and pub/sub messages from clients whilst maintaining ordering would be critical... Yet if you look around the industry; callback-based event handlers are still the norm for most application logic and people are still not using queues where they should be. People think of queues as some expensive/bulky system with overhead which requires additional architecture (e.g. RabbitMQ, Kafka, STOMP, NSQ) and always requires exactly-once delivery, they have not tried to make the idea a core part of their application logic. Software today is FULL of race conditions because of this blind-spot. Yet I still cannot communicate my message. It's too difficult to explain the benefits.
socketcluster
·पिछला माह·discuss
Sure. A lot of these things tend to go together. Weird hacks is a bad one. Those AI agents love to cheat and if they see highly elaborate hacks in the code, they won't hold back either.
socketcluster
·पिछला माह·discuss
True. I've worked on projects which required updating 3+ repos for each feature. Required carefully-timed staggered deployments.

It's often a sign of poor separation of concerns. Tight coupling and low cohesion.

On a good codebase with microservices, this should happen on rare occasions, but not every single time you add a new feature. Been there. Agreed those are particularly hard to work with using AI.
socketcluster
·पिछला माह·discuss
It's based on my experience as a software engineer who has worked on both clean and messy codebases with AI.

It's a very different experience with a messy codebase. In this case, the agent spends most of its time trying to gather the relevant context and it's like a game of whac-a-mole. The agent burns through tokens and can take a long time to resolve the issue with a lot of human intervention required. I would say it takes possibly just as long or longer than a human engineer would. Also, psychologically, the temptation for the engineer to trust the AI is massive because they don't want to load themselves up with all that ugly, complex context. They are more likely to let the agent create more hacks on top.

On a relatively well-structured codebase with loose coupling and high cohesion, the experience is usually very positive, mind-blowing, even; because it feels like the agent is reading your mind and fast-forwarding you. You don't need to correct it as much. And when you do, it's usually minor things.

The first case represents a net loss of value because tech debt is being added and compounding the complexity each time a problem is 'solved'. On the other hand, the second case is a significant speedup, for me, I would say it's at least a 5x speedup. I love using AI in this way. I'm in control and not at the mercy of the agent.
socketcluster
·पिछला माह·discuss
It makes me wonder about the state of their codebase if devs needs to consume more than $1500 per month.

It's interesting that AI is finally forcing businesses to think about coding maintenance costs though.

When I started working on https://saasufy.com/ as a dev tool many years ago, I was frustrated that no big company cared about software maintenance costs and I really couldn't imagine a world where maintenance costs would be a problem (which is what my platform was addressing). So this is one positive thing from my perspective, I guess. But how much longer before people put 2-and-2 together and realize that architectural complexity is the leading cause? That's the real moment I'm still waiting for.

Will what's left of the socio-economic system be sufficiently capitalist that I will be able to capitalize on that? That's my next problem.
socketcluster
·पिछला माह·discuss
I've been advocating for this approach for years. It's useful for any kind of data processing. You can't avoid race conditions without using some kind of queueing mechanism and you need backpressure to measure queue capacity. I built this into every aspect of https://socketcluster.io/ - From pub/sub channels, RPCs to event listeners.