Hacker News new | past | comments | ask | show | jobs | submit | the1024's comments login

Yes, good call out - I actually wrote a bit more about this and how we arrived at our solution with `tach`.

[0] https://www.gauge.sh/blog/the-trouble-with-all


(author here)

borplk hit this right on the head - the public/private distinction not sufficiently nuanced enough to handle the requirements of more complex codebases.

To put your example in other words, I simply want baz scoped to foo. baz may be public for all members and sub-modules of foo, but external uses of baz outside of foo would create brittle and unwanted dependencies across my codebase.


My experience primarily comes from scale-ups, where the companies grew fast and hired fast.

Without putting specific companies on blast, I hear about this problem consistently from growth stage startups that scaled on Python. It's a common reason people reach for microservices - trying to use network boundaries to cover for the lack of module boundaries.

Ideally you can trust coworkers; unfortunately that's not always the case. Here's a quote from a developer in response to the article in another forum: """ It can even be very useful sometimes to be able to import private stuff. In a large ecosystem where you use many modules from other teams, you might need to use some private functionality. """ If something is available for an individual developer that solves their problem, often they're not thinking about the fact that it's private or creates a brittle dependency with no contract.


There's a decent (if fairly biased) comparison on monorepo tooling here: https://monorepo.tools/

Note that it's written by nx.dev (TS monorepo tool), so well worth taking the specific comparisons with a large grain of salt. Useful to understand what is out there though!


Bazel (originating from Blaze inside Google) is great but very heavy/takes a lot of work to adopt. It's likely the gold standard if you're working with a large polyglot repo.

As a python dev, I've been frustrated with existing solutions, which is why we built Tach to solve some of the problems we've faced, particularly around organization and isolation - https://github.com/gauge-sh/tach

Pants is another great build system out of Twitter that has seen widespread adoption - https://www.pantsbuild.org/


Typically teams won't have access to the code that's being deployed on the other side of the network boundary. This physical separation is overkill though; something like CODEOWNERs and https://github.com/gauge-sh/tach can do this without incurring remotely the same overhead.


Google famously still primarily maintains a monorepo, but they absolutely don't deploy a monolith. They published a paper last year that describes an approach that is quite close to what they have internally - https://dl.acm.org/doi/pdf/10.1145/3593856.3595909

Effectively, by setting strong boundaries between modules, they can develop on their application as if it was a monolith, but at runtime, separate those modules physically deploy them as micro-services. This solves a lot of the versioning issues (since the app is rolled out atomically) and correctness issues (easier to reason through a monorepo).


We've encountered the exact same problem in the past, and open sourced our solution to enforce those boundaries! https://github.com/gauge-sh/tach Alongside CODEOWNERs, you can effectively constrain teams to focus on where they need to be.


The Problem

We built bridge to solve the most frustrating part of any new project — infrastructure. Whenever you spin up a new Django project, you usually have to manually configure Postgres, background workers, a task queue, and more. The problem is amplified when you go to deploy your application — hosting providers don’t understand anything about what you’ve configured already, so you have to run through an even more complicated process to set up the same infrastructure in a deployed environment.

The Fix

bridge is a pip-installable package that spins up all of the infrastructure you need, and automatically connects it to your Django project. By adding a single line to your Django project's settings.py file, bridge configures everything for you — this means you don’t need to mess with DATABASES, BROKER_URL, or other environment variables to connect to these services.

bridge also gives you the access you need to manage these services, including a database and Redis shell, as well as a Flower instance for monitoring background tasks.

When you’re ready to deploy, bridge can handle that as well. By running bridge init render, bridge will write all of the configuration necessary to deploy your application on Render, including a button to trigger deploys straight from your README.

If you don’t want all of these services, (say you already have a database, and just want to add background workers) bridge supports that too! It can automate everything you need and nothing you don’t.

How it Works

bridge is built on top of Docker, so you get fully isolated and up-to-date versions of Postgres and Redis from the beginning. Celery and Flower need to run on top of your app code, so we hook into runserver to spin these up as background processes. If you need to spin things down, bridge stop will conveniently shut down all services that it’s started.

Coming Soon

In the future, we want to add support for more services (jupyter, mail/mailhog etc), more hosting providers (Heroku, Railway, etc.), and more configuration (env vars, optional dependencies, etc).

bridge is and always will be fully open source. Please give it a try and we’d love any feedback!

Github - https://github.com/Never-Over/bridge

Docs - https://never-over.github.io/bridge

PyPI - https://pypi.org/project/python-bridge


We went through a relatively controversial process w.r.t. enforcing this at my last co. What it really came down to was intent vs. impact - the intent of the change was to enforce better development practices, especially across junior engineers that had shipped monster prs containing multiple bugs that were extremely hard to catch ("the easiest way to ship a one line change is in a thousand line pr").

This worked reasonably well in terms of forcing junior engineers to reason harder about what an atomic change should look like, but also impacted senior folk that were making atomic changes that encompassed broad areas of the codebase. We eventually reverted the change and relied on implementing CODEOWNERs to enforce senior devs to request changes when PRs got out of hand.

There's definitely nuance to enforcement of best practices across an entire organization; haven't really seen it done well although I've primarily worked at startups.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: