5 ms·
Go has lots of packages. They are easily discoverable on godoc.org or just some googling. There is a cultural skepticism about the overuse of packages. There a
by cdoxsey 8y ago
Go has lots of packages. They are easily discoverable on godoc.org or just some googling.
There is a cultural skepticism about the overuse of packages. There are occasions where the STD lib copied a function instead of adding an import for example. Like many things in Go this pushback is needed but sometimes goes too far.
But maybe single function packages in npm we're a bad idea.
Anyway caching is a mixed bag in my opinion. Local per-thread caching is often better than a global cache as it avoids contention. It's also trivial to implement with a map and requires no special coordination.
It does require rethinking how you design a solution to a problem. FWIW that design process tends to lead you down a better direction anyway for producing distributed systems.
For example one giant, randomly distributed Kafka topic with a global redis db for a cache is probably a lot worse off than a system with more predictable data locality on the consumers.
- mrjn 8y ago(co-author here) The number of Go libraries tend to be just slightly below the number of their users (dramatically speaking). Libraries are hardened by repeated usage by many different users who each bring their own special use cases and improve them to bring them to production quality. Go has no platform where certain well-written libraries can be recommended and get more exposure. Thus, they don't tend to mature more than the specific use case they get written for, provided they are still being maintained. Arch Linux is a great example of giving well-doing packages more exposure by upgrading an AUR to community to core/extra. That way, more users gather around packages improving them even further. To the second point about per-thread caching, Go does not expose threads to end-users. So, there's no concept of thread-local. What you're describing results in lock striping, which has contention issues as described in the post.
- sagichmal 8y ago> Go has no platform where certain well-written libraries can be recommended and get more exposure. Godoc.org is that platform, it serves the purpose. Others in the module universe are under development. > To the second point about per-thread caching, Go does not expose threads to end-users. So, there's no concept of thread-local. What you're describing results in lock striping, which has contention issues as described in the post. In Go you'd have to orchestrate this locality yourself, i.e. a fixed worker (goroutine) pool each with its own cache. This is probably less work than it sounds. Generally, Go does encourage you to author solutions to your specific problem, rather than adapting a general-purpose library. This is almost as much a part of the ethos of Go as implicitly-satisfied interfaces, or "share memory by communicating", or any of the other proverbs. Maybe Go takes it too far. But effectively no other language exists at this point on the spectrum, and I'm happy that we have at least some representation over here; I think lots of programmers live here, too, and appreciate the tradeoffs.
- mrjn 8y ago> Godoc.org is that platform, it serves the purpose. Godoc.org is great. But (beyond documentation) it is at best a search engine, providing equal platform to all libraries however production ready or broken they might be. Unless I'm missing something, it does not intend to promote certain libraries over others, the same way as AUR -> community -> core works in Arch (which is the model I think is missing in Go). > In Go you'd have to orchestrate this locality yourself, i.e. a fixed worker (goroutine) pool each with its own cache. Having many small caches within the same process would result in more misses per key, which if it results in disk accesses would not be ideal or might be worse than contention. Moreover, being able to spin Goroutines as and when required to branch off a big job into smaller tasks is the beauty and benefit of Go compared to other languages like C++ or Java, where you must start a thread pool upfront and shoot tasks off to it.
- Foxboron 8y ago>the same way as AUR -> community -> core works in Arch (which is the model I think is missing in Go). Arch packager here. It doesn't quite work like that. The distinction between community and extra is largely based on who packages it, it used to be defined as above 5% usage. The distinction between that and core is that core is considered essential to the distribution. No package is going to go from AUR to core without replacing some integral part of the system.
- mrjn 8y agoI see. Then I guess there's a different model that can more accurately represent the idea of giving certain well-written/actively-maintained/popular packages a special platform than others to make it more enticing for wider community to adopt those. The underlying issue is that building a production ready library doesn't just happen -- it needs one or few initial authors and (along with a large group of users) a group of dedicated power users who can then continue to maintain the library and optimize it for their usage, in turn developing it enough to be considered production ready.
- cdoxsey 8y ago> Thus, they don't tend to mature more than the specific use case they get written for, provided they are still being maintained. This is all a bit abstract. There are plenty of go libraries which are suitably mature for production use. For example Google's cloud libraries or Amazon's AWS libraries. There's a platform for communication of issues and releases: Github. I guess I haven't really had an issue with it... The only problem I've had is the messiness of versioning, but there's been solutions to that for a long time (godep, govendor, glock, etc...) > To the second point about per-thread caching, Go does not expose threads to end-users. So, there's no concept of thread-local. What you're describing results in lock striping, which has contention issues as described in the post. Sorry for the confusion. I did not mean thread-local variables. I meant breaking up your workload across mutiple goroutines so that you don't have to use shared state. For example suppose you receive a message with an org ID. You start 8 workers, all data for (id % 8 == 0) goes to worker 0, (id % 8 == 1) goes to worker 1, and so on. Each worker maintains a local map of data and no mutex is needed to coordinate access, because only one goroutine can use the data at a time. So there's no lock-striping and no contention issues. This is the recommended approach for Go concurrency: > Do not communicate by sharing memory; instead, share memory by communicating. I understand that this sort of approach doesn't work for every problem, there's not always an easy way to split up the data like this (you might end up with hotspots for example). But I feel like that conclusion needs to come after a bit of reflection, instead of reflexively reaching for a global object + mutex. (Not saying that's what you guys are doing... just a common issue I've seen working on distributed systems with developers new to Go)
- mrjn 8y agoNot to nitpick here, but Google's cloud libraries and Amazon's AWS libraries work because there're probably a dedicated team of engineers who're assigned to these projects, considering cloud platforms are supposed to make these giant orgs a ton of money. When Google needs something, it gets built, corrected and optimized quickly (e.g. Go context library). Open source / crowd sourcing doesn't work that way.
- jzoch 8y agoA thread local cache is not going to be as performant esp. w.r.t. large data sets. There is a huge area between global redis db for a cache and thread local cache. At some point you have a large data set that is accessed by many different actors at different intervals. Having each application cache (and re-cache if they go down) is not always sustainable.