5,215 karma · joined September 23, 2014
This was true of all software they used, but MSDN was the most expensive and blatant. If it didn't have copy protection, they weren't buying more than one copy.
We were a software company. Our own software shipped with a Sentinel SuperPro protection dongle. I guess they assumed their customers were just as unscrupulous as them. Probably right.
Every employer I've worked for since then has actually purchased the proper licenses. Is it because the industry started using online activation and it wasn't so easy to copy any more? I've got a sneaky feeling.
RocksDB has a pluggable filesystem layer (similar to SQLite virtual filesystems), they can read blocks from the SQLite cache layer directly without needing to fake a RocksDB file at all. This is how my solution (I've implemented this before) works. Mine is SQLite both places: one SQLite file (normal) holds cached blocks and another SQLite file (with virtual filesystem) runs queries against the cache layer. They can do this with SQLite holding the cache and RocksDB running the queries.
IMO, a little more effort would have given them a better solution.
In practice I have found that it's very painful to thread state through your program. I ended up offering global variables, which provide something similar to but worse than generalized reference semantics. My language aims for simplicity so I think this may still be a good tradeoff, but it's tricky to imagine this working well in a larger user codebase.
I like that having only value semantics allows us, internally, to use reference counted immutable objects to cut down on copying; we both pass-by-reference internally and present it as pass-by-value to the programmer. No cycle detection needed because it's not possible to construct cycles. I use an immutable data structures library[2] so that modifications are reasonably efficient. I recommend trying that in Herd; it's almost always better than copy-on-write. Think about the Big-O of modifying a single element in an array, or building up a list by repeatedly appending to it. With pure COW it's hard to have a large array at all--it takes too long to do anything with it!
For the programmer, missing reference semantics can be a negative. Sometimes people want circular linked lists, or to implement custom data structures. It's tough to build new data structures in a language without reference semantics. For the most part, the programmer has to simulate them with arrays. This works for APL because it's an array language, but my BASIC has less of an excuse.
I was able to avoid nearly all reference counting overhead by being single threaded only. My reference counts aren't atomic so I don't pay anything but the inc/dec. For a simple language like TMBASIC this was sensible, but in a language with multithreading that has to pay for atomic refcounts, it's a tough performance pill to swallow. You may want to consider a tracing GC for Herd.
[1] https://en.wikipedia.org/wiki/Internet_Archive#Operations
IMO, don't mention aws-nuke at all. This isn't the same kind of product as aws-nuke, which is explicitly the "One-click cleanup workflows" category in your "Not designed for" box. Your tool is for accounts that I'm not trying to nuke. So why invite the comparison? These tools are not intended for the same use case.
Spitballing here, I'd think you would want to lean into the cost savings aspect of deleting orphaned resources. aws-nuke is about cleaning out disposable AWS accounts. CleanCloud is about cloud cost optimization on real production/staging accounts.
A final note: it seems like the name CleanCloud is already used by a laundry service provider. You still have time to pick a different name for which you can take the top Google spot.
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Hibernat...
c*: 2GB per vCPU
m*: 4GB per vCPU
r*: 8GB per vCPU
x2idn/x8g: 16GB per vCPU (!)
x2iedn/x2iezn/x8aedz: 32GB per vCPU (!)1. When I personally see database timeouts at work it's rarely the database's fault, 99 times out of 100 it's the caller's fault for their crappy query; they should have looked at the query plan before deploying it. How is the error-handling code supposed to know? I log timeouts (that still fail after retry) as errors so someone looks at it and we get a stack trace leading me to the bad query. The database itself tracks timeout metrics but the log is much more immediately useful: it takes me straight to the scene of the crime. I think this is OP's primary point: in some cases, investigation is required to determine whether it's your service's fault or not, and the error-handling code doesn't have the information to know that.
2. As with exceptions vs. return values in code, the low-level code often doesn't know how the higher-level caller will classify a particular error. A low-level error may or may not be a high-level error; the low-level code can't know that, but the low-level code is the one doing the logging. The low-level logging might even be a third party library. This is particularly tricky when code reuse enters the picture: the same error might be "page the on-call immediately" level for one consumer, but "ignore, this is expected" for another consumer.
I think the more general point (that you should avoid logging errors for things that aren't your service's fault) stands. It's just tricky in some cases.
Mozilla allows minification but you're required to provide the original buildable source. Mozilla actually looks at the code and they reject updates all the time.