[HN Gopher] Reality Check for Cloudflare Wasm Workers and Rust
       ___________________________________________________________________
        
       Reality Check for Cloudflare Wasm Workers and Rust
        
       Author : comagoosie
       Score  : 115 points
       Date   : 2021-09-18 13:55 UTC (9 hours ago)
        
 (HTM) web link (nickb.dev)
 (TXT) w3m dump (nickb.dev)
        
       | jfrunyon wrote:
       | I believe a zip file could be streamed - most of the file
       | metadata is duplicated between both the 'central directory
       | record' trailer _and_ a header in front of each file. In other
       | words, the first thing in the zip file is a header that you can
       | use to extract the first file, followed by that file, followed by
       | the next file 's header...
        
         | stavros wrote:
         | You can, yes. You can even download the header, open the zip
         | file, choose which files to extract, and only download those.
         | This is possible with HTTP today, and has been for decades.
        
       | brundolf wrote:
       | > I guess I'll stick with my error prone Javascript Workers or,
       | more likely, spend an afternoon migrating to a minimal Typescript
       | setup.
       | 
       | If the OP wants a zero-config typescript experience (assuming
       | Deno isn't available on Cloudflare workers), I can't recommend
       | esbuild enough
        
         | wtetzner wrote:
         | There's also js_of_ocaml if a good type system is desired.
        
           | brundolf wrote:
           | I think that's out of scope for the OP's needs/wants. They
           | like TypeScript for catching basic API mistakes, the only
           | thing they don't want is configuration headaches. I didn't
           | get the sense they would be interested in learning a new
           | language for this use-case, especially since I'm going to
           | guess Cloudflare doesn't publish OCaml types for their
           | JavaScript API.
        
           | Yoric wrote:
           | When we wrote opalang, the size of generated JS was
           | problematic, despite serious efforts at minimizing it. Does
           | js_of_ocaml do better?
        
         | comagoosie wrote:
         | I think this is an excellent suggestion (I'm OP / author), and
         | one one can add just a dash to this for typechecking. Minimal
         | setups are appreciated, especially when one has many small
         | projects.
        
           | brundolf wrote:
           | Glad I could help! Esbuild won't do the actual type-checking
           | for you, but your editor will (hopefully also without
           | configuration)
           | 
           | I'll put it this way: I've spent enough time with Webpack and
           | Babel and TSC at this point that I can troubleshoot most
           | issues without too much difficulty. But despite that I reach
           | for esbuild every time I possibly can, because I just don't
           | _want_ to mess with all that stuff if I don 't have to.
        
       | dafelst wrote:
       | Great overview OP, and it's nice to see a kind of "in-between"
       | scenario tested, i.e. not a super fast web request or
       | transformation, rather something more akin to a lightweight batch
       | job. It may not be quite a "recommended" use case but it is
       | always interesting (for me at least) to see how these sorts of
       | services' capabilitied can be pushed and or (gently) abused. The
       | memory and code size limitations do seem very restrictive right
       | now, which is a shame though.
       | 
       | Seeing WASM evolve as the new sandboxed runtime target dejour is
       | a super interesting and I love that it is bringing more variety
       | of very powerful but traditionally backend or systems languages
       | to the web.
        
       | up6w6 wrote:
       | iirc the compilation time of wasm in Cloudflare Workers is very
       | problematic[1] and right now it contradicts their idea of running
       | low latency fast scripts, does anyone know if anything has
       | changed ?
       | 
       | https://community.cloudflare.com/t/fixed-cloudflare-workers-...
        
         | kentonv wrote:
         | Yes, it has changed, which is why the thread you linked has
         | "[FIXED]" in the title. Details can be found later on in the
         | thread.
        
       | dgreensp wrote:
       | I think the one-sentence version of this is that Workers are
       | meant for small, undemanding tasks (for example, they have tight
       | memory limits and don't have great performance), so using them to
       | do "serious number crunching" at the edge, which is the
       | advertised use case, seems questionable.
       | 
       | I think the blurb about the downsides of Wasm is just too
       | generic, it's a sort of "why Wasm isn't preferable to JS in all
       | cases" for the uninitiated. It may not be meant to imply that
       | number crunching is the use case.
        
         | kentonv wrote:
         | > I think the one-sentence version of this is that Workers are
         | meant for small, undemanding tasks
         | 
         | Not at all! We're building a platform on which you can build
         | your entire app. What you say may have been the case four years
         | ago when Workers launched, but since then we've added Durable
         | Objects, Cron triggers, much longer time limits, etc. We very
         | much believe Workers can be a stand-alone alternative to other
         | cloud providers.
         | 
         | > for example, they have tight memory limits and don't have
         | great performance
         | 
         | This isn't true.
         | 
         | "Performance" is a vague term, you need to clarify the use case
         | and what you're measuring. But, I can't think of what you could
         | mean by "don't have great performance", that seems to imply
         | that they execute code slower or something, which just isn't
         | true at all. In many cases, Workers perform much better than
         | you could achieve with any other platform, due to the ability
         | to spread work and data across the network and move it close to
         | where it's needed.
         | 
         | The "memory limit" on a single worker instance is 128MB, but
         | Cloudflare runs many instances of the worker around the world,
         | so across the network you're really getting many gigabytes of
         | memory. By building a distributed system based on Durable
         | Objects, you can harness the memory of many instances to use on
         | a single task. Workers definitely biases towards distributing
         | load across the network rather than running a single fat
         | instance of your server, but that just means Workers makes it
         | easy to build apps that scale to much higher.
         | 
         | What this article is highlighting is that Wasm is still an
         | immature technology. That is, unfortunately, just a fact.
         | There's still work to be done, and progress is being made, but
         | it's still early. The code footprint issue (because every app
         | must bring along its own language runtime) is the biggest
         | blocker. We hope to see that solved with dynamic linking.
         | 
         | But, Workers isn't primarily based on Wasm. The vast majority
         | of Workers are written in JavaScript, where these issues don't
         | exist. Workers runs JavaScript just as fast as any Node.js
         | server, and runs it closer to the client resulting in better
         | latency.
        
           | azakai wrote:
           | Small note on this:
           | 
           | > What this article is highlighting is that Wasm is still an
           | immature technology.
           | 
           | I assume you meant on the server, where wasm is fairly new,
           | that's true. On the browser, wasm is a mature and stable part
           | of the Web platform.
           | 
           | Otherwise very good points!
        
             | kentonv wrote:
             | I don't, actually. Wasm is immature in the browser, too,
             | for the same reasons. Writing a client-side web app
             | entirely in Wasm generally doesn't work well today because
             | you'll force the client to download much more code before
             | the page can run. Lots of work is being done to improve
             | this, like adding built-in garbage collection to the Wasm
             | runtime so that apps written in GC'd languages don't need
             | to ship their own. Dynamic linking will help too, assuming
             | that language runtimes are allowed to be cached across
             | different sites.
             | 
             | In both environments there are certainly use cases where
             | Wasm provides huge advantages. But those use cases are
             | still narrow. Over time it'll grow but there's still tons
             | of work to do.
        
               | azakai wrote:
               | Ah, I think we disagree on the goals of wasm.
               | 
               | Yes, if you want to write a client-side webapp you run
               | into limitations. That wasn't one of our main goals when
               | we created wasm, though! It would be great if that
               | materializes - more options are always good - but
               | JavaScript is frankly the right tool for 99% of sites and
               | we never intended wasm to directly compete with JS there.
               | 
               | Wasm _is_ stable and mature for solving the needs of
               | sites like Google Earth, Unity games, Figma, Meet, Zoom,
               | etc. Those require more than what JS can offer and wasm
               | is the perfect fit for the relevant parts of them.
               | 
               | On those websites wasm is often the difference between
               | shipping and not shipping. That's a huge deal, and why
               | wasm has been focused there. Other use cases like
               | replacing JS with wasm might offer some benefits in
               | speed, perhaps, but the impact of that would be smaller
               | (but it could eventually apply to a wider set of sites,
               | potentially).
        
               | kentonv wrote:
               | Right. Same for server. You can do most of what you want
               | to do in JavaScript and it'll be fine. Use Wasm to fill
               | in the gaps where JavaScript doesn't work. That's a good
               | strategy today with Cloudflare Workers, too.
               | 
               | It's when people want to write entire apps entirely in
               | their language of choice, and want to accomplish this
               | using Wasm, that the technology is still missing things.
               | A lot of people want to do this, both on the browser side
               | and the server side.
        
           | ignoramous wrote:
           | > _We very much believe Workers can be a stand-alone
           | alternative to other cloud providers._
           | 
           | Time for Durable Workers: Run one Worker (per Durable Object
           | instance) with higher RAM and wall-time ceiling, capable of
           | serving WebSockets and WebRTC data-channels (and gRPC, if we
           | are being ambitious)?
           | 
           | > _The "memory limit" on a single worker instance is 128MB,
           | but Cloudflare runs many instances of the worker around the
           | world, so across the network you're really getting many
           | gigabytes of memory._
           | 
           | Throw-in the zonal Cloudflare cache (which is free upto 500MB
           | per cached-object) and some clever workarounds, a lot could
           | be done. May be Cloudflare dev-rel could to add it in a
           | "Workers SDK" of sorts to make this easier, or the eng team
           | can work towards seamlessly exposing it to Workers instances
           | as _swap_ space? :D
        
         | csomar wrote:
         | > I think the one-sentence version of this is that Workers are
         | meant for small, undemanding tasks (for example, they have
         | tight memory limits and don't have great performance)
         | 
         | That could be most web apps functionalities. Things like
         | registration, authorization/authentication, sending emails,
         | store/retrieve data, etc...
         | 
         | > so using them to do "serious number crunching" at the edge,
         | which is the advertised use case, seems questionable.
         | 
         | Cloudflare workers don't run in the background. They block the
         | HTTP request. For serious computation, Cloudflare should offer
         | background workers that can run for extended periods of time.
         | [1]
         | 
         | 1: This could be tricked by triggering an async request, but
         | there is no push API to get notify the "App" of the result.
        
           | eloff wrote:
           | Workers does have a Cron like functionality. My memory is
           | fuzzy but it's been around for a while.
           | 
           | https://developers.cloudflare.com/workers/platform/cron-
           | trig...
        
             | csomar wrote:
             | Assuming you pull results every 1 second, that's 86.4k
             | requests a day for each potential user you have. Another
             | solution, is it have a single CRON worker that watches for
             | all notifications, kinda a basic implementation for a Push
             | API.
        
               | eloff wrote:
               | A request per second per user is just bad architecture.
               | You will need something like you're saying to batch
               | processing in some way.
        
           | wrkronmiller wrote:
           | Given HTTP pipelining and fetch() promise semantics, I'm not
           | sure there's a practical benefit to pushing results instead
           | of "blocking" the original request.
        
             | csomar wrote:
             | If you want to run something in the background whether the
             | user page is still active or not. Once the computation is
             | complete, it pushes a notification to the user or trigger
             | other workers.
        
           | kentonv wrote:
           | > Cloudflare workers don't run in the background. They block
           | the HTTP request. For serious computation, Cloudflare should
           | offer background workers that can run for extended periods of
           | time.
           | 
           | You can use `event.waitUntil()` to schedule a task that runs
           | after the HTTP response has completed, and you can use cron
           | triggers to schedule background work in the absence of any
           | HTTP request at all. You can even build a reliable async
           | queuing system on top of cron triggers and Durable Objects,
           | though at the moment it's a bit DIY -- we're working on
           | improving that.
        
         | brundolf wrote:
         | I for one hadn't thought about the cost of shipping your own
         | standard library with every bundle, so it was informative for
         | me
        
           | wibagusto wrote:
           | WASM tasks shouldn't need a full standard library. If you
           | statically compile against any library it should only keep
           | the pieces used.
        
             | brundolf wrote:
             | That's fair, but still, you'll be pulling in a lot of
             | really fundamental stuff that JavaScript gets for free.
             | String manipulation, fundamental data structures,
             | iterators, HTTP, JSON (de)serialization, etc.
        
               | mst wrote:
               | One of the examples he mentioned was 200Kb.
               | 
               | That's still a lot more than "a single file of
               | javascript", certainly, but it's not _that_ bad.
               | 
               | Trade-offs all the way down, as ever.
        
             | merb wrote:
             | I'm not sure but if you need any string manipulation at all
             | it will be really hard to not use the rust std?
        
               | brundolf wrote:
               | I think their point is that what's referred to as "tree-
               | shaking" in the JS world is (I'm pretty sure) normal and
               | standard for most statically-compiled languages like
               | Rust. So you won't bring in anything you _don 't_ need,
               | though you will still be bringing in lots of stuff you
               | _do_ need
        
               | azakai wrote:
               | Generally true, but just to add to that, in languages
               | like Rust and C++ you often end up including stuff you
               | don't need due to toolchain limitations. For example,
               | indirect calls (from Rust traits or C++ virtual methods)
               | are hard to get rid of in general.
               | 
               | This is a pretty significant cause of bloat in practice,
               | sadly, but toolchain improvements may help in the future.
               | So for now, JS's advantage of the standard library being
               | in the VM is pretty significant.
        
       | wibagusto wrote:
       | Correct me if I'm wrong but the memory copying issue is not an
       | issue if you pass an array buffer into WASM from JavaScript. In
       | that scenario there's no data copying. E.g. similar to how you'd
       | pass the canvas data to WASM for direct manipulation.
        
         | azakai wrote:
         | No, this is an issue currently, both for network data and
         | canvas data.
         | 
         | All wasm instructions can do is read and write from the wasm
         | Memory that the wasm is initialized with. They can't even refer
         | to separate things like a new ArrayBuffer from JS. So you do
         | need to copy.
         | 
         | Newer wasm additions like reference types allow an ArrayBuffer
         | to be referred to inside wasm, but only as an opaque reference
         | to the entire thing (an externref). There is still no ability
         | to actually read and write from it inside wasm.
         | 
         | The solution to this is BYOB ("bring your own buffer") APIs,
         | which JS is adding. They are experimental atm though. Here is
         | the relevant one here:
         | 
         | https://developer.mozilla.org/en-US/docs/Web/API/ReadableStr...
         | 
         | Note how you pass in a view to the JS API. That can be a view
         | into the wasm memory, letting the browser directly write data
         | into there, and then wasm can operate on it immediately.
        
         | Matthias247 wrote:
         | So how do you fill that arraybuffer from Javascript datatypes
         | (e.g. strings which describe the request)? The answer is "by
         | copying the relevant data" - which is exactly what the bridging
         | code between JS and WASM does. You can only avoid that if the
         | source data is already plain byte arrays and not javascript
         | objects.
        
       ___________________________________________________________________
       (page generated 2021-09-18 23:01 UTC)