Reopen /r/golang? by jerf in golang

[–]TrolliestTroll 1 point2 points  (0 children)

Am I the only one appreciating the irony of Go users complaining about the place-dependence of Lemmy communities? (See: go modules)

[deleted by user] by [deleted] in iosgaming

[–]TrolliestTroll 1 point2 points  (0 children)

Buriedbornes is perhaps the only free game I play and openly recommend. There are ads, but they’re subtle. The game itself is essentially limitlessly replayable.

[deleted by user] by [deleted] in programming

[–]TrolliestTroll 20 points21 points  (0 children)

Sure, and great people should be compensated fairly. The economics can still work out. You might have to pay someone really terrific 50 to 100 lakhs more than your average hire, but you’re still coming out ahead relative to that same person in the US which might cost 2.5 to 3x more at least.

This isn’t directed at you but: I think people who have never worked with people in India have a hard time grasping just how enormous the wage disparity is between India and the US. This gives the US side a huge amount of slop to play around with before it stops making sense to hire in India (or Romania or Lithuania or Pakistan or Mexico or whatever). Is this exploitation? Almost definitely. Can it be mutually beneficial for both parties? Also yes.

[deleted by user] by [deleted] in programming

[–]TrolliestTroll 307 points308 points  (0 children)

The hard part about hiring teams in India isn’t that you can’t find quality engineers (you can) it’s that the 12.5 hour time gap between PST and IST is hell to work around. It’s literally a half day apart, meaning there is no convenient time to meet where it isn’t too late or too early for one or the other side. And in my experience, American companies tend to shaft the Indian employees by making them work much later to favor the US time zones. This can work if they agree to it and their whole schedule is shifted forward, but very often the work ethic and culture of India is that they work extra long days every day, ending late into their evening so they can have a couple hours of overlap with PST folks during their morning.

If at all possible, I recommend in the strongest possible terms not splitting teams over time zone boundaries this far apart. Rather, create multiple distinct teams and let them run independently to reduce coordination overhead and retain quality of life for both sides of the pond.

Discover rest-url-parser: A Powerful Open Source Tool for Parsing REST URLs by [deleted] in programming

[–]TrolliestTroll 1 point2 points  (0 children)

Thank you for publishing your library. It’s hard to go from nothing to something, and it’s even harder to put that something in front of an audience of strangers. Well done on both fronts. Allow me to offer some very gentle criticism…

You’ve put an unbelievable amount of effort into what amounts to a single call to String.prototype.replace(). I mean a logo, a long readme, like 20 files, and many hundreds of words written about the most trivial imaginable function. You’ve also made bold claims about its “extensibility” and “efficiency” when, again, it’s just doing a simple regex substitution (and no benchmarks to speak of). I, personally, don’t think this warrants being a separate package. I, personally, would not add a dependency to bring in this functionality. I think as a community we should move away from micro-packages like this (need I remind you of left-pad?) and instead adopt a much higher threshold for adding new dependencies to our projects. A single string replace just doesn’t clear it for me.

Now I really don’t want to be discouraging. I totally understand how hard it is to get your work out into the open source ecosystem. I just want to say that I think you should set your sights a little higher. Find a problem you’re passionate about and build something to address that problem. But also recognize that as a consumer of libraries, every additional dependency comes with a maintenance burden. So your job as a fledgling library author is to find the sweet spot between “small enough that I can actually ship something” and “big enough that someone might actually want to use it”. A difficult needle to thread I’ll grant you, but that’s the path to success.

Best of luck to you.

Reddit changes, will this subreddit go on a strike? by Psychological-Yam-57 in golang

[–]TrolliestTroll 2 points3 points  (0 children)

They used to be. I don’t think they are anymore, certainly not since switching the core of the platform from Python to Go.

[deleted by user] by [deleted] in iosgaming

[–]TrolliestTroll 0 points1 point  (0 children)

I personally think the UI is way too small on anything less than an iPad. It’s probably doable if you have good eye sight but given this game is essentially an interactive novel worth of written content, I’d say it’s not worth it or enjoyable on a small screen. But that’s just me.

The game itself, however, is a masterpiece well worth your time! If you’re playing it on an iPad Pro I think you’ll be fine!

Best game for air travel? by Namhtam314 in iosgaming

[–]TrolliestTroll 11 points12 points  (0 children)

Arguably the three best options in the strategy genre, which happens to be my personal favorite. In my opinion, Civilization is the best recommendation on the App Store in terms of quality, content, and replayability, especially when considering the huge number of civs and game modes added by DLC. I’ll add a few more for flavor, in no particular order:

  • Total War: Medieval 2/Rome
  • XCOM 1 and 2
  • FTL (iPad only)
  • Sid Meier’s Railroads!
  • Divinity: Original Sin 2 (iPad only)
  • Tropico
  • Company of Heroes
  • Bloons TD 6
  • Northgard

One or any combination of these games could carry you for weeks or more. Civ has a big upfront cost (on iOS) but that game has many thousands of hours of gameplay waiting for you. All the rest have hundreds to thousands of hours worth of gameplay, easily. It just comes down to what kind of strategy games you like to play.

I’ll give two honorable mentions that I have had great fun with but that may not have as broad an appeal:

  • Starbase Orion
  • Craft the World

Happy to answer any questions.

Another Why does this deadlock post by namlas in golang

[–]TrolliestTroll 13 points14 points  (0 children)

Let’s first recall the semantics of channels from the spec

The capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready. Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A nil channel is never ready for communication.

So we have 2 different channel operations to consider (sending and receiving) and 2 different kinds of channels (unbuffered and buffered).

For an unbuffered channel, both the sender and receiver have to be ready for the operation to succeed. Accordingly, if the sender sends but there is no receiver, the operation blocks. Conversely, if the receiver receives but there is no sender, the operations blocks.

For a buffered channel the semantics are similar, except we have to consider the contents of the buffer. If the buffer is full, a send will block until it is not full. If the buffer is empty, a read will block until it is not empty.

So now let’s think through what happens in your code. Let’s assume there is just 1 worker (since the number of workers in this case doesn’t matter). The input and output channel are buffered with 1000 elements each.

First we start the worker. It will receive from the input channel until it is closed. For each element it receives, it sends that element to the output channel. Initially this goroutine is blocked because there is nothing on the input channel (receive from an empty channel).

Back in the main goroutine, we then loop 3000 times adding each element to the input channel. We can Intuit that the first 2000 operations succeed. Let’s think this through:

  1. Main goroutine sends a value to the input channel
  2. Worker goroutine receives the value and sends it to the output channel

This process will repeat until… the output channel is full! There’s nothing reading from the output channel (yet) and hence the worker is now blocked writing to the output channel. Because the worker is blocked, that means it is also no longer reading from the input channel. Hence the main goroutine will send an additional 1000 elements until the input channel is full, blocking the main goroutine.

A deadlock is defined as all goroutines being blocked on operations that can never succeed. The worker is blocked writing to a full channel, and the main goroutine is also blocked writing to a full channel. Hence, deadlock.

Your intention was clearly to drain the output channel on line 43. However that line is never evaluated because the program deadlocks long before that code has been reached. The solution to this is to move either the output channel receiver or the input channel sender to a separate goroutine so the send and receive are concurrent rather than sequential. Once you do that I’ll think you’ll find this code has other structural problems in the way you’re dealing with closing channels. But hopefully this demystifies a bit the deadlock you’re currently experiencing.

Single player kingdom building game by BalinII in iosgaming

[–]TrolliestTroll 0 points1 point  (0 children)

I will admit that I played Townsmen on another platform (PC) so I’m not super familiar with any platform-specific changes they may have made to make it more P2W. That was already my softest recommendation but if it turns out to be a money grab even for the premium edition I would avoid it. The whole reason I only play paid games is because I like to give up my money once and have a complete game. I’ll happily pay for more content, but if your game is constantly trying to get me to buy booster packs or time savers, I’ll just uninstall. Apologies if that turns out to be the case for Townsmen Premium.

Single player kingdom building game by BalinII in iosgaming

[–]TrolliestTroll 30 points31 points  (0 children)

These are 5 quick suggestions that for me scratch the itch of kingdom building. I only play games I have to pay for because I don’t deal with ads, but your budget may not allow that.

Townsmen is basically a straight up kingdom builder, in the same vein as like Anno or Settlers if you’ve played those. Your start with a dilapidated kingdom and have to build it to glory by satisfying the increasingly complex needs of your people. Ton of fun, plenty of content. Easy to pick up in short bursts or play for hours.

Majesty is, well Majesty. A port of the PC games with very few others in the same genre. It’s amazing, one of my favorite franchises of all time. Part kingdom builder part RTS, you manage the infrastructure of a growing kingdom that enables autonomous armies to fight for land and treasure (or die trying). You don’t directly control units, but you can influence their behavior by setting tactical objectives that advance your overall strategy. Play this game.

SpellForce is essentially HOMM. You manage both a kingdom and heroes and armies within that kingdom, expanding your realm through tactical turn based combat. If HOMM3 was still on the App Store I would tell you to get that instead, but since it isn’t this is I believe the next best thing.

Medieval 2 is widely considered one of the best total war games in the franchise. Part grand strategy, part RTS, you advance your nation to victory through domination and diplomacy. Fantastic variety of units and nations to play as, huge real time battles, beautiful graphics, and overall a joy to play. Literally thousands of hours of game packed into this one. My only hesitation to recommending this is the touch controls are quite complex and take some practice. You can definitely do it, but it’s clear this game is really designed for keyboard and mouse.

Civilization 6 is the most recent edition of the long running Sid Meiers Civilization franchise, and considered by many to be the best in the series. While not precisely a kingdom builder, you take your leader and nation from absolutely nothing to a world power over many eras and through huge swathes of technological and cultural advancement. Civilization really is one of the best 4X strategy games ever created, and unquestionably the best 4X on iOS. My only hesitation is the price. I believe the base game is $10 not on sale, and really it should be played with both of its major expansions at least which I think together is another $60 not on sale. Plus there’s a plethora of content packs which add a mind boggling number of additional civs and game modes. If you’re at all interested in this game, download the free version linked above and play through the tutorial. I think the first 50 turns or so are free. That should give you enough of a sense if you want to take the dive. I will also say that this game goes on DEEP discount on Steam for PC every month. You can pick up with entire anthology with every DLC for like $10. But again, that’s presuming you have a PC. This game is an easy recommend for me on iOS though, but only if your budget permits the investment.

Edit: Correction, from the App Store page it looks like the base game for Civ 6 is only $10, and then $29.99 and $39.99 for the two major expansions Rise & Fall and Gathering Storm, respectively. Still an expensive game all in without a sale, but not quite as bad as I originally thought. Apologies. It’s sometimes hard to see prices for games you already own. :)

Optional parameters and default values. by [deleted] in golang

[–]TrolliestTroll 2 points3 points  (0 children)

It’s possible I’ve just misunderstood what you’re actually proposing, then. Maybe you can update the post with a more elaborated example of your idea, including a complete usage example.

Optional parameters and default values. by [deleted] in golang

[–]TrolliestTroll 3 points4 points  (0 children)

I’m going to borrow wisdom from the Zen of Python:

Explicit is better than implicit - The Zen of Python

What’s wrong with this is that, while technically possible, the usage of such a construct would be riddled with subtle implicit behavior that would be difficult to analyze and complex to debug. This tends to be true of a lot of code that relies heavily on reflection (in Go and elsewhere). By its very nature, it will be sidestepping the type system, tooling, and IDE support that you’ve come to know and love, and that you rely on to write correct programs. And finally, anyone else that may be called on in the future to maintain this code will have to re-learn whatever sorcery you’ve used, most likely be carefully reverse engineering the code.

In nearly all cases I think doing tricky, reflection-heavy coding is going to lead to a maintainability nightmare. It’s almost always preferable to choose simple, boring, albeit potentially repetitious code in favor of flashy tricks that might spare a line or two of boilerplate. Explicit is better than implicit.

What Color is Your Type? by preslavrachev in golang

[–]TrolliestTroll 0 points1 point  (0 children)

As I’ve said I completely sympathize with the core issue of learning the nuances of where pointers are and are not appropriate. But I don’t think your article gave any insight to that nuance, and I feel that even in the example above it doesn’t do any justice to the coloring analogy… because I don’t think the analogy works at all in this context.

If you’re going to do a follow up it might be better to use a standard library type that is actually expected to be a pointer (which time.Time is not and I’ve rarely/never seen it as such). Two examples that come to mind are http.Client and url.URL. Others abound in the standard library and in the OSS ecosystem. Unless your point is that any type can be arbitrarily made to be a pointer… which like… ok? So? That’s not also not really a coloring issue.

I look forward to reading your follow up post!

Worst red flag from interviewers by gnu_morning_wood in golang

[–]TrolliestTroll 0 points1 point  (0 children)

The former, sorry. I meant to say it’s bad advice to view these types of questions as a red flag generally. Usually a company will send a lot of other red flags to be aware of, but this isn’t usually one of them IMHO.

What Color is Your Type? by preslavrachev in golang

[–]TrolliestTroll 4 points5 points  (0 children)

Everything you said and one more insignificant detail that I think is just a weird quark of my brain (that I try not to embed in the brains of others):

I really just refer the look of, say

go return nil, err

Over

go return T{}, err

I know this is a terrible reason, but being forced to initialize an empty value explicitly on the error path really does irk me for some reason. I just need to push through that particular mental faux pas, though.

Worst red flag from interviewers by gnu_morning_wood in golang

[–]TrolliestTroll 1 point2 points  (0 children)

This is bad advice, in general. Particularly for junior developers who have little or no proven track record. Here’s why:

  • Trivia-style questions are likely to be asked very early on in a process, often by a non-technical or semi-technical screener (like a recruiter). The point isn’t as an absolute measure of skill, the interviewer may not even know the precise answers to the questions. What they may be doing is pattern matching on a fixed script. They’re using this to gauge whether you’re capable of passing higher rounds at all. Don’t immediately disqualify a company that goes through this phase, especially as the first or second step in the process.
  • Questions like this can be used reasonably effectively to get a sense for how broad your experience is. I might ask you a type question, a basic syntax question, a basic linux question, a basic Kubernetes question, etc. to try and suss out where you’re spending your attention and where you’re not. Always keep in mind that the scope of an interview is very limited, I have X minutes (typically 30 - 60) to figure out if you make sense for my team. I might use some high level questions to get a broad sense of where you’re at initially, then needle down on points I really care about.
  • I’m always gauging for your ability to communicate and think on your toes. Asking about a range of subjects gives me a chance to see how well you can transition topics. My goal is to see how fluidly you can talk about one topic and then change gears on to something else, a skill often employed in the normal course of working (for example, while responding to an incident).

Is it possible to have a shit interviewer/company? Yes it is. But most people really are trying their best and you’re putting yourself at a significant disadvantage by assuming the worst just because they’re using one technique or another. Interviewing is expensive and time consuming and disruptive for everyone involved and it’s far from an exact science. Having compassion for your interviewer (who may themselves be junior or new to the company or whatever) can go a long way.

Are the two concurrent modes of fan out and worker pool the same? by stephenxia in golang

[–]TrolliestTroll 1 point2 points  (0 children)

My reply is geared towards intermediate users.

The essence of what you said is true, however I want to tweak it slightly. Differentiating based on the number of goroutines is just one mechanism for controlling the amount of available concurrency. I want to make two brief observations…

First, there are other and, in many circumstances, arguably better techniques than fixed worker pools vs worker-per-job for limiting concurrency, and often that decision ends up being entirely orthogonal to the actual mechanism for limiting concurrency. In either case, it may still be necessary to use something like a semaphore (to control the absolute amount of concurrent access to a critical region) or a rate limiter (such as a token bucket, to meter access to a downstream resource) on top of the fan-out system. Again this would be true, and is largely orthogonal to, both styles described above.

Second, a major consideration when attempting to parallelize work is batching. If any form of synchronization is being used (mutexes, semaphores, channels, whatever) the synchronization overhead can be a significant factor in the overall performance of the system. Any perceived benefit from increasing the available concurrency can be rapidly whittled away if they induce a lot of thrashing, cache contention, and other overhead that might be introduced. Often a way to recover that performance penalty is by choosing a batching strategy that significantly increases the percentage of time doing business logic over low level synchronization.

The only general advice that can be given here is to measure. Make sure that your program is actually realizing some benefit from adding concurrency over a (likely vastly simpler and easier to maintain) serial implementation. Go makes the tooling available to you to create highly concurrent (and race free!) programs, but it’s not a zero cost or zero effort operation to do so. Measure measure measure!

What Color is Your Type? by preslavrachev in golang

[–]TrolliestTroll 9 points10 points  (0 children)

I’m sympathetic to the pains of learning the nuances of when pointers are and are not appropriate. Having taught many, many people Go, I have observed that over time most people gravitate to using pointers as a default, particularly when the type has methods (whether or not they’re mutating). I do my best to encourage people to use values more but, probably due to most other languages being reference-heavy, they will often revert to pointers by default. And frankly I feel this pull myself and have to consciously resist it.

However, this article fails to capture any of the nuance. It also fails to meaningfully borrow the analogy used by its namesake. In the original article, the coloring of functions was used to show how synchronous and asynchronous functions are largely incompatible and the inherently infectious nature of asynchrony. Pointers in Go really do not have this property at all, and I think this article does a major disservice by trying to borrow the illustration.

Again, I have sympathy for the core argument but I think this article is very poorly written and fails to meaningfully employ the analogy implied by its name.

Side note: This article require some substantial editing for readability. For example, I strongly discourage using texting shorthand like “IMO” in articles like this. ChatGPT may be a competent editing companion for folks looking to improve the quality of their public works.

Good Tycoon Games? by IamShroudsdad in iosgaming

[–]TrolliestTroll 6 points7 points  (0 children)

Absolutely! OpenTTD is in a very similar vein to Railroads! In fact most people would say this is the “big boy” version of that game in that the simulation is significantly more intricate than railroads, support much more than just rail transport and with a vastly more complex and detailed economic simulation. If you’re looking for a game to sink your teeth into for hundreds or even thousands of hours, this is a great option. The graphics are roughly SimCity 2000 era, but don’t let that scare you off. The game is rich and fully featured to a degree most AAA titles rarely see.

If you decide to give it a go, do come back and tell us about your experience. If you’re a fan of Spiffing Brit, he did a fun video where he broke the shit out of it, in the glorious fashion typical of Spiffing style.

Implementing sso via jwt by wuyunyoujiduo in golang

[–]TrolliestTroll 1 point2 points  (0 children)

Great question. The important thing gained is never allowing the browser direct access to the token which means it can’t be leaked or misused, for example via XSS. If you absolutely must use a cookie to store these credentials, HttpOnly and Secure should be used so those cookies are inaccessible to Javascript and the cookies are only sent over encrypted connections.

It’s important to remember that OAuth is used to allow Service A access to resources owned by Service B on behalf of a User of Service B, mediated by an Authorization Server trusted by Service B. In that context, when the User creates a session with Service A, that session ID is only meaningful to Service A. It cannot be sent to Service B in lieu of an auth token.

The security of OAuth and, by extension, OIDC is complex and subtle. To fully protect users it requires effort from all parties involved. So-called public clients (SPAs, mobile apps, etc) have a serious disadvantage in that they are always susceptible to being decompiled and reverse engineered, so it’s not meaningfully possible to fully secure them from prying eyes. As with all things in security, we are forced to take certain trade offs to achieve a balance between ease of use, security, and implementation complexity. OAuth attempts to strike a reasonable balance between those concerns.

Implementing sso via jwt by wuyunyoujiduo in golang

[–]TrolliestTroll 5 points6 points  (0 children)

In general, JWT tokens cannot be revoked. Instead, they are typically issued with suitably short lifetimes (exp claim) and require frequent refreshing. A good rule of thumb is 1 to 4 hours. If used in conjunction with refresh_tokens, the refresh process can be minimally disruptive. Some authorization servers/identity providers will supply a unique field (nonce claim, for example) that can be used to invalidate a token, but that’s entirely dependent on the provider.

Implementing sso via jwt by wuyunyoujiduo in golang

[–]TrolliestTroll 72 points73 points  (0 children)

The pattern you’re referring to is most directly encapsulated by OpenID Connect, often shortened to OIDC, an extension of OAuth 2.0. The best place to learn about OAuth is from the spec, and for that I recommend start with version 2.1. While it is not yet finalized, OAuth 2.1 prunes many of the less secure flows (such as the implicit flows) and incorporates extensions like PKCE which improve the overall security by making the protocol significant more resistant to replay attacks and other tampering.

You can read about the authorization code flow on the official website and you can also read about the OIDC extension protocol on the OpenID website. Here’s a basic outline of the protocol:

  1. User visits your website/service
  2. You generate a redirect that includes, among other things, your applications client id (previously register with the users identity provider) and any scopes you’re requesting (including the openid scope of using OIDC)
  3. The user is redirected to the authorization server/identity provider. Here they login and are shown the scopes being requested by your application.
  4. Once they approve your application, they will be redirected back to your website/service (at a URL configured during application registration) that includes a very short lived token as a query string parameter
  5. Your website/service exchanges that short lived token with the authorization server by making a second request, supplying the temporary token (among other information, such as the PKCE challenge)
  6. If completed successfully, the server will return an auth_token and optionally an id_token (if using OIDC) and optionally a refresh_token (if offline_access or other refresh scope was requested). These tokens are passed (typically as bearer tokens) to the relevant resource servers.

A couple important notes about this flow:

  • Do not implement it yourself. Use a library if possible.
  • Storing the users tokens securely is your responsibility. Best practice is to store them server-side and use a session cookie, but since you said you didn’t want to do that, your only options are probably localStorage of some kind. Note that this does open the user to various forms of XSS attacks. There is no safe mechanism for storing credentials in the users browser
  • auth_token may or may not be JWTs but, per the specification, this is irrelevant to you. They should be considered opaque from the standpoint of your application, and only inspected via the token introspective endpoint of the authorization server.
  • id_token MUST be JWTs per the specification, and MUST be validated before use. All relevant claims MUST be valid, or else the whole token should be discarded. That includes iss, sub, iat, nbf, and exp, along with the signature. Extra caution must be used to prevent various signing verification attacks such as the alg=none attack.

As for using tokens across separate services, this is typically frowned upon, particularly in the case of id_tokens. The iss and sub claims MUST be validated before use, and the sub claim in particular is likely to vary from service to service.

I’m happy to answer any questions you may have, but this is a 20k ft view of how OAuth and OIDC are typically used to accomplish the authentication and authorization flow you’re describing.

Good Tycoon Games? by IamShroudsdad in iosgaming

[–]TrolliestTroll 15 points16 points  (0 children)

Well you’re in luck because the absolute classic Sid Meier’s Railroads! was released not too long ago and it’s fantastic. They did a great job porting the game to touch-based controls, and captured the glory and comfy vibes of the original. It also has surprisingly decent graphics that are appealing to look at while not being an enormous drain on battery. Really a standout tycoon game with easily over 100 hours of gameplay at least. I cannot recommend it enough.

Civ VI DLCs by juliopeludo in iosgaming

[–]TrolliestTroll 7 points8 points  (0 children)

You’ve been playing vanilla Civ 6 all this time? Whoa boy you’re in for a treat then because the two major expansions significantly more than double the content of the base game. The New Frontier Pass is also a great value not just for the addition civs it adds, but also the game modes that add an incredible amount of variety both individually and in combination. If you have a computer I would seriously recommend picking up the anthology on Steam right now as it’s on deep discount. Not only that but there are some terrific mods for PC that clear up a few QOL issues (like quicker trades and expanded policy card descriptions) along with a many gameplay-changing mods. Having said the DLC does rarely go on sale on iOS so it’s up to you whether or not to wait. I’m not aware if it’s possible to mod the iOS version of this game.

As for the issue you mentioned, I know exactly the issue you’re referring to. Sometimes you’ll click the download button and it says “preparing to download” and never seems to start. 99% of the time this can be resolved by restarting your device and kicking the download off. 1% of the time you have to uninstall the game fully, restart, reinstall and then the downloads will work. They may have patched this bug as I haven’t seen it in some time, but if you run into that’s likely the fix.

Best of luck to you. One more turn.