gilgad13
Joined 16 years ago
Joined 16 years ago
1. Just don't. Work on open source on the weekends, etc.
2. Do it as part of a "commoditize your complements" strategy.
3. Work at a company that is so large they can fund open source development as part of their advertising strategy.
4. Gather together some expertise in existing open source projects and sell consulting. Crucially, you'll probably need to build on top of some existing open source install base or name recognition. Redhat didn't start the linux project or the gnu userland, Percona didn't write mysql, etc. In some sense you are now one of the leaches that posts such as this one complain about.
The fundamental piece in common here is that the open source bit isn't the main value driver for the business.
I think as an organization grows to some combination of available resources and severity of an outage this view becomes more and more common.
As evidence that channels should be used rarely, and only in small scopes, consider the number of places chan is used in the standard library.
How does this differ from what large players like Dell are offering under the "hyperconverged" moniker. For example, Dell's Vxrail[0] appears (from marketing speak, anyway) to be a single rack with integrated networking and storage that you can ask to "just start a vm".
[0]: https://www.dell.com/en-us/dt/converged-infrastructure/vxrai...
> You have no soul as a company at that point, you’re just trying to make money with other people, rather than help people with a problem that you know. You may think you have an idea, but it’s not good enough yet.
I think this is the crux of the difference. If you want to have a successful startup, you have to believe that you deserve to exist and believe you have something unique to offer. You cannot just "show up and listen" and get paid the big bucks.
I think Lua is a bit unique in this for two reasons. First, they have in intentional open-source but not open development model. Second, because of the way that Lua is embedded inside other projects, there is more willingness to implement backwards-incompatable changes. I'm sure this is a negative for some who want to build a larger, less fractured community, but it has advantages for language cohesiveness.
Interesting that this does not use `encoding/gob` by these criteria. I think `encoding/gob` is a nice example of what is possible with reflection, and I've certainly learned techniques from reading its implementation, but I haven't seen very many uses in the wild and this certainly would seem like a vote of no-confidence.
Rather, there is a certain amount of objective risk in alpine environments, and the more time you put yourself in that environment, especially in locations you aren't familiar with, the greater the chance that something will eventually go wrong.
I'm always surprised by the number of famous alpinists who weren't killed on their progressive, headline-capturing attempts but rather on training attempts and lesser objectives.
Given all this, what does layering give us?
It gives some deduplication, but only a crude form. It gives some reproducibility from building off a well-known base and tag, but not full reproducibility. It gives some security benefit from building off a well-known base, but not as large a benefit as standard package managers provide.
I would be excited to see a image distribution system based off of something like casync, maybe with an initial rootfs formed through image-focused distributions like yocto[1]. The embedded device ecosystem has been concerned with reproducibility, image signing, and incremental updates for awhile and I think their approaches are very applicable to container images.
Its the difference between "we talked about many things, including this issue" and "we need to meet to discuss this issue". I find the second starts everyone off on a defensive foot, regardless of peoples' best intentions.
And yes, I do think this, "but everyone else is doing the same thing so it isn't really our fault" attitude is a problem.
* Use `reflect.Value.Select`[1]. Having to reach for reflect feels ugly for such a common case, and the performance of the reflect-select is much lower than the native select.
* Create a single channel owned by the reader, pass it to each writer, and arrange for this channel to be closed when the final writer exits, through a waitgroup. There is an example under "Parallel digestion" in the Go Concurrency Patterns blog post[2]. Note the little details to get right. We must launch a separate goroutine to monitor the waitgroup / channel closure. If we accidentally do it in-line at the wrong level, everything will work fine if the total number of items written to `c` is less than `c`'s capacity, but will hang once a worker becomes blocked on `c`. Additionally, the waitgroup is threaded directly into the writers, which may be more difficult if those are implemented in some other generic package.
* Wrap the above pattern up into a `merge` function, such as the one under "Fan-in, Fan-out" in the Go Concurrency Patterns post[2]. The lack of generics means we will have to copy-paste this function everywhere we want to use it. Additionally, this launches a goroutine for every channel being watched, which strikes people as "expensive" for such a simple operation.
* We can construct a function that takes two channels and launches a goroutine that selects between the two and writes to a merged output channel. By constructing a tree of these we can merge an arbitrary number of channels. This is really just an optimization of the above.
None of these options are particularly intuitive. Too often I've instead seen developers create a single channel owned by the reader and either:
* Assume it is never closed and the reader doesn't terminate until the application does
* Rely on some external mechanism to know when to stop reading. If the reader can stop reading without confirming that the writers have stopped writing, this can lead to the writers becoming blocked on sending into this channel, which may prevent them from performing necessary cleanup actions (signaling `.Done()` on a waitgroup, for instance) that cause hangs in other areas.
* Thread a cancellation ctx through every reader and writer. This ensures that nothing hangs, but can result in messages that are sitting in the the channels being dropped. If other areas of code have an assumption like, "every accepted request will receive a response", this can break that.
In addition, many developers have a gut instinct to add some amount of buffering to their channels, which usually results in these backpressure / channel issues being papered over during low-load unit tests, only to rear their head during higher load integration tests or in production, when the debugging story is much more difficult.
In this design, determining the threshold for similarity may require the participation of a third-party "oracle" or "judge" component.
I believe these are the exact technical advancement the top-level poster was contrasting with cable networks, so the distinction matters here.