4 ms·
Great point about time. At work we've adapted github.com/WatchBeam/clock and it's helped a lot. Thanks for blogging about your work on juju! Despite Go already
by zalmoxes 10y ago
Great point about time. At work we've adapted github.com/WatchBeam/clock and it's helped a lot.
Thanks for blogging about your work on juju! Despite Go already being five years old, many of the patterns around building large applications are only emerging now.
- akerro 10y agoGo was released in 2007, it's 10 years old. Rust is closer to be 5yo, it's 7yo according to wikipedia.
- bpicolo 10y agoWasn't released to public at all until late 2009.
- jimktrains2 10y agoIt only became stable in mid-2015. https://blog.rust-lang.org/2015/05/15/Rust-1.0.html https://blog.rust-lang.org/2015/05/15/Rust-1.0.html
- NateDad 10y agoComparing 1.0's is a much better comparison, except in cases where there was huge adoption before 1.0.
- jimktrains2 10y agoI wouldn't say rust was hugely adopted before 1.0 (not that it's hugely adopted after, either).
- NateDad 10y agoYes, sorry, wasn't saying that either Go or Rust were an exception, just trying to forestall the inevitable "but what about X thing that was used by everyone and is still 0.9" :) For Go vs. Rust, I think a comparison of 1.0 releases is perfect.
- stymaar 10y agoI think gp meant that for some platforms it can make sense to count even 0.x releases (nodejs is the best example I think), even though for most it doesn't (including Rust and Go).
- f2f 10y agoGo was announced to the world on November 10th, 2009.
- weberc2 10y agoThis is a minor nit, but it seems to me that it would have been easier to configure the unit with a shorter timeout duration rather than mocking out the time functions. Am I mistaken?
- zalmoxes 10y agoIt really depends. You might want to test something that requires days/weeks expiration. I would agree that the Clock interface is a bit large. In personal projects I prefer to just have something simple like timer func() time.Time
- weberc2 10y agoI don't understand your argument. What's special about a days/weeks that would prevent you from shortening this value for your tests? In other words, if I want to test my timeout logic, it should be independent of the timeout value, so I should be free to use a shorter timeout value in my timeout tests.
- jerf 10y agoMocking out the time functions means you don't get any race conditions. If you try to just twiddle with how long the time functions run, you still never quite know how long to set them. Bear in mind that even rather generous timeouts like a full millisecond to set a map entry in another goroutine can still fail if your system's CPU is loaded or the system is in swap, and spurious test failures are spurious test failures regardless of their cause. Often with this sort of code you're testing in one goroutine and the test code is in one or more other goroutines. If your test code can emit something down a synchronous channel, then your test code can also be sure it is staying in sync. I mean, even to test with "extra special small test timeouts" still means you're writing in extra test structure, you might as well just use one of these time mocking things. (In fact, you should generally always use time mocking libraries. In all languages, direct access to the system clock that can not be easily redirected for testing is at least a code smell and could possibly even rise to the level of "antipattern".) I have a lot of places in my Go test code where my test code is deliberately pushing things down channels. It's one of the top reasons my test code often still ends up being in the same package, so it gets private access to those channels for safe, properly-sync'ed testing. (Not that I'm really all that concerned about trying to test only the public interface; I don't have a lot of troubles with that anyhow. YMMV.) I also have some places in my code where I have channels in the private interface of some goroutine server whose sole purpose in life is to sync with the tests. This generally appears when I have some server that I am sending a message that I expect to change the state of the server, but for which there is no reply. In order to verify that the proper changes have occurred in the data structures of the server, I need to sync with the change before I do the check. Having a simple struct{} channel whose sole purpose in life is to synchronize works well enough for that.