https://htmx.org logo
Join Discord
Powered by
# htmx-general
  • p

    proud-librarian-99598

    08/20/2022, 8:02 PM
    Indeed, what used to be a method call, is now a network call and the consequences of that are: the callee might not be there, the callee might got the request but was unable to respond, the callee might just be slow to respond, etc
  • m

    mysterious-toddler-20573

    08/20/2022, 8:03 PM
    https://martinfowler.com/bliki/FirstLaw.html
  • p

    proud-librarian-99598

    08/20/2022, 8:04 PM
    If you ever think of implementing them , first read https://microservices.io/book It shows all the complexities you need to deal with if you want to do it properly.
  • m

    mysterious-toddler-20573

    08/20/2022, 8:05 PM
    Copy code
    System event                   Actual latency Scaled latency   
        ------------                   -------------- --------------
        One CPU cycle                  0.4 ns         1 frame (1/60 s)
        Level 1 cache access           0.9 ns         2 frames
        Level 2 cache access           2.8 ns         7 frames
        Level 3 cache access           28 ns          1 s
        Main memory access (DDR)       ~100 ns        4 s
        Intel Optane memory access     <10 μs         7 min
        NVMe SSD I/O                   ~25 μs         17 min
        SSD I/O                        50–150 μs      0.5—2 hrs
        Rotational disk I/O            1–10 ms        0.5—5 days
        Internet call: SF to NYC       65 ms          1 month
        Internet call: SF to Hong Kong 141 ms^3       2 months
  • p

    proud-librarian-99598

    08/20/2022, 8:05 PM
    I can assure you that a lot of people will think twice before going that route 😀
  • q

    quiet-nightfall-51817

    08/20/2022, 8:15 PM
    This. It's not about scaling the resulting microservice. It's about scaling your development department. Monoliths are fantastic from 1 to about 20-ish developers. You can force them up to about 100-ish people (consider: Dunbar's number). Past that, the complexities of getting development done with that many people all working on one codebase/deployment get excessively hairy, and breaking things off into separate services just to keep up your cadences starts overriding the losses you take in dealing with all the other service overheads. Microservices solve FAANG scale problems, where your development department might be thousands, tens of thousands, or even approaching 100,000 like Amazon.
  • q

    quiet-nightfall-51817

    08/20/2022, 8:21 PM
    About the only other major reason for services and especially microservices, is if you need something to be isolated from your main app for some reason. Like at $DAY_JOB, we have two things that make strong sense as separate services. One has a very peculiar network setup requirement (custom VPNs to a third party service provider) that nothing else in our stack does. The other requires an excessively hairy cross-language shared library integration that makes building it a colossal pain due to version pinning across language tooling boundaries. Either of those being added into our main repo would drastically slow our development process cycle for builds, testing, and deployment.
  • p

    proud-librarian-99598

    08/20/2022, 8:25 PM
    Totally agree that there are very valid reasons to have them, but it should not be the default IMO
  • p

    proud-librarian-99598

    08/20/2022, 8:27 PM
    Just as SPA’s should not be the default 😀
  • q

    quiet-nightfall-51817

    08/20/2022, 8:27 PM
    Yeah. It will usually become very obvious when you need them. "We can't deploy feature X, because team Y is taking forever to finish their work on feature Z, and blocking the build". Or "this build takes 10 hours because we have to compile a custom tool chain from scratch for this one library that only a single rarely used feature uses".
  • m

    mysterious-toddler-20573

    08/20/2022, 8:29 PM
    What I don’t understand is the micro part. I get splitting out services, but I’d default to relatively large services, rather than loads of small ones.
  • q

    quiet-nightfall-51817

    08/20/2022, 8:33 PM
    Well, in the two cases I described that I deal with, the isolated parts are individually pretty small. One makes a single network UDP call to a third party and then parses the result. If not for the fact that it requires this weird custom VPN setup, it'd be about 2 dozen total lines of code with exactly one entry point. As is, it's got 4 entry points now (1 for major use case, 2 to control/report on the failover plan for dealing with the multiple VPNs to the vendor's different datacenters for redundancy, and 1 for metrics/monitoring), and is still only a few hundred lines of code. It's as small as possible because that's the only part that needs to be isolated.
  • q

    quiet-nightfall-51817

    08/20/2022, 8:35 PM
    The other one is an ML-model solution. Using the particular ML library from our main implementation language is a giant pain in the ass, because the app is not written in C++ and the library is. It requires very specific tooling to make it work (library versions, linker versions, compiler versions, etc). Likewise, there's only one real function ("do the model analysis thing") that needs isolation, and only because of the tooling nonsense. So again, 3 actual endpoints, though a bit more code to deal with cross-language loading of shared objects and what not.
  • q

    quiet-nightfall-51817

    08/20/2022, 8:37 PM
    IMO, those are the good sorts of reasons to do microservices. Bad reasons are because your org is structured so that teams too small and too specific. Though once you've gone the service route, it can be tempting to just keep shaving off more and more things into separate services, rather than be disciplined and do proper libraries/modules bundled into large services.
  • q

    quiet-nightfall-51817

    08/20/2022, 8:38 PM
    A bit of it is locality of behavior, in a way. "Everything about our interaction with thing X is in one service that only deals with X". You have a vendor you deal with? You have one microservice that interacts with that vendor, and everything specific to it is in that service, so if the vendor changes behavior, there's exactly one place to fix it. You could do that in a library or module, if you factor it well, but forcing a network boundary basically guarantees it.
  • q

    quiet-nightfall-51817

    08/20/2022, 8:47 PM
    I have to admit, early on in my career, due to a stint at Amazon, I bought into the whole microservices thing pretty hard. Eventually, though, I ended up hitting every single one of these https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing and then more over time. Now I too tend to prefer monoliths, or at least "chunky" services wherever I can possibly get away with it.
  • h

    hallowed-architect-39752

    08/20/2022, 8:49 PM
    so what explains the mass adoption of microservices? is it mostly a buzzword/trend? because I doubt most people are running organizations with hundreds of devs to warrant using microservice architectures. my guess is that it's because of the adoption of cloud services.
  • h

    hallowed-architect-39752

    08/20/2022, 8:49 PM
    idk
  • q

    quiet-nightfall-51817

    08/20/2022, 8:50 PM
    partly cloud services, partly because every one believes, wishes and dreams they are big enough to have the problems that companies like Amazon, Google, Microsoft, etc have.
  • q

    quiet-nightfall-51817

    08/20/2022, 8:52 PM
    Also partly because a lot of people go through those companies at some point in their career, and get trained by a doctrine that makes sense for companies at those scale, and then transmit it to smaller companies when they move on. "This is how we did it at Google!" "Ooooh, must be good for us too, then".
  • q

    quiet-nightfall-51817

    08/20/2022, 8:56 PM
    People at those companies also write lots of blog posts and papers and give presentations at conferences. And people with less experience consume these and then think "this must be a best practice, I should do the same".
  • q

    quiet-nightfall-51817

    08/20/2022, 9:06 PM
    Related thought I just had: some of it is also driven by tooling and ecosystems. In javascript land, especially node side, everyone is used to breaking things down into components so small they seem ridiculous to anyone in any other ecosystem. If you write lots of node stuff, decomposition past the point of logic and sanity is just kinda... normal. Likewise, if you're in python land, working with the packaging is such a colossal pain in the ass that the only two paths are to stuff literally everything in the biggest monolith you can and pin everything or divide everything out so small so that no cross-library compatibility versioning issues can ever arise.
  • h

    hallowed-architect-39752

    08/20/2022, 11:38 PM
    thanks for explaining. and yeah handling Python dependencies makes me want to cry
  • l

    little-thailand-67217

    08/21/2022, 4:15 AM
    I know i am most likely misinterpreting this but I see the docs say the websocket extension is included in 1.7+ although i cant seem to get it to work. Following the example of the old way works although i cant get the extension way to connect
  • l

    little-thailand-67217

    08/21/2022, 4:28 AM
    Oh never mind I found it. I thought it was included in the minified release i was using from unpkg but i have to manually add it (also from unpkg). I suppose this is to keep htmx as small as possible which makes sense. The first extension example is not overly clear whether i am using the inbuilt one or a custom one and the
    path/to/ext/debug.js
    should probably be an unpkg path to complete the example e.g.
    https://unpkg.com/browse/htmx.org@1.8.0/dist/ext/debug.js
    . Just my two sense.
  • h

    happy-knife-63802

    08/21/2022, 6:34 AM
    @mysterious-toddler-20573 any thoughts on this?
  • m

    mammoth-family-48524

    08/21/2022, 9:31 AM
    Hello! 👋 I'm having trouble figuring out an htmx:swapError. I tried stepping through the code and it appears to be erroring at line 3049
    newActiveElt.focus(focusOptions);
    . Any ideas? This the HTMX code that is causing it.
    Copy code
    <form hx-post="/invite-client" hx-swap="outerHTML">
            <sl-dialog label="Invite client" id="invite-client-dialog">
                
                <sl-input name="email" type="email" label="Carer's email address" value="" required="" size="medium" invalid="">
                        
                </sl-input>
                <sl-button slot="footer" variant="primary" type="submit" id="invite-client-save" size="medium">Send invitation</sl-button>
                <sl-button slot="footer" variant="text" id="invite-client-cancel" size="medium">Cancel</sl-button>
            </sl-dialog>
    </form>
  • m

    mammoth-family-48524

    08/21/2022, 9:34 AM
    I just realised the focus errors that come after this one are also HTMX ones 🤦‍♂️
  • m

    mammoth-family-48524

    08/21/2022, 9:47 AM
    The debugger is saying
    newActiveElt = sl-button#invite-client-save
  • m

    mammoth-family-48524

    08/21/2022, 10:04 AM
    I'm guessing this is actually a combo of HTMX+Shoelace. This is the line 70 part in the error
    Copy code
    // src/components/button/button.ts
    var SlButton = class extends s {
      constructor() {
        super(...arguments);
        this.formSubmitController = new FormSubmitController(this, {
          form: (input) => {
            if (input.hasAttribute("form")) {
              const doc = input.getRootNode();
              const formId = input.getAttribute("form");
              return doc.getElementById(formId);
            }
            return input.closest("form");
          }
        });
        this.hasSlotController = new HasSlotController(this, "[default]", "prefix", "suffix");
        this.localize = new LocalizeController(this);
        this.hasFocus = false;
        this.variant = "default";
        this.size = "medium";
        this.caret = false;
        this.disabled = false;
        this.loading = false;
        this.outline = false;
        this.pill = false;
        this.circle = false;
        this.type = "button";
      }
      click() {
        this.button.click();
      }
      focus(options) {
        this.button.focus(options);    **<-- line 70 is this one**
      }
1...789790791...1146Latest