RegExr: A website for interactive regex prototyping with syntax highlighting - <AUTHOR> http://regexr.com/ <comment><USER2> Unfortunately, RegExr does not color-code the different capturing groups.

For example, replace the RegExr sample regex with "([A-Z])\w+\s\w(\d.\d)" and compare[1][2] its color coding capability to the other regex helpers.

The other sites such as regex101.com & debuggex.com will delineate the capture groups within the matched text using different colors. This is very helpful for complex captures because making the boundaries visible can reveal bugs in your thinking of what substrings the regex is actually capturing.

(I don't intend to be negative. If capture group color-coding is an easy coding enhancement for RegExr, consider my comments as mentioning a minor nit.)

[1][https://regex101.com/r/eB5jY1/1](https://regex101.com/r/eB5jY1/1)

[2][https://www.debuggex.com/r/mci3WLNmHGTEatf6](https://www.debuggex.com/r/mci3WLNmHGTEatf6)

(couldn't find a way to enable /g global on debuggex.com (even tried PCRE option) but color boundaries still show up on the 1st capture group)

<comment><USER3> Just wanted to chime in and give my recommendation for regex101.com that parent links to. This is by far the best regex "composer" I have ever used, on or offline.

<comment><USER4> Yup. regex101.com is really awesome and has been a time saver for me many times.

</comment></comment></comment><comment><USER5> Nice work :) Looks like this tool puts the emphasis on the pedagogical aspect.

For development, the most fantastic tool that I know of in this space is debuggex. Here is an example with roman numbers:

[https://www.debuggex.com/r/Xqlv3QcAuw_EgPSM](https://www.debuggex.com/r/Xqlv3QcAuw_EgPSM)

<comment><USER6> Dude, that is way cool. This is like one step away from FSMs.

<comment><USER7> You can step through the FSM on Debuggex by using the sliders :)

</comment></comment></comment><comment><USER8> My favourite is still [https://regex101.com](https://regex101.com)

Example regex: [https://regex101.com/r/wY0rM7/1](https://regex101.com/r/wY0rM7/1)

<comment><USER9> Came here to give this a mention, it's a really valuable tool

</comment></comment><comment><USER10> I had the older version bookmarked [http://gskinner.com/RegExr/](http://gskinner.com/RegExr/) which now redirects to this site. Some other good sites that I've used are:

[http://regviz.org/](http://regviz.org/)

[https://regex101.com/](https://regex101.com/)

[http://osteele.com/tools/rework/](http://osteele.com/tools/rework/)

[http://www.rexv.org/](http://www.rexv.org/)

[https://www.debuggex.com/](https://www.debuggex.com/)

<comment><USER11> I'd add [http://regexpal.com/](http://regexpal.com/) for historical completeness. It's the first such tool I used and prefer it even today. Very sad that from what it seems Steven Levithan sold entire domain recently and is not updated anymore. Even permalinks broke last year. (I'm a bit worried, what's up with Steven.)

</comment></comment><comment><USER12> RegExr looks really nice, but my go to is still [http://rubular.com](http://rubular.com).

<comment><USER13> What do you think makes it better? I think the UX on rubular is much cleaner.

Don't they both serve a different flavor of regex?

<comment><USER14> Rubular uses Ruby's regex engine (Oniguruma/Onigmo). Regexr uses your browser's RegEx engine.

That doesn't make it "better", but it does mean they have slightly different purposes. You can use Ruby specific regex features with Rubular, so it is "better" for Ruby regex development.

As a general principle, I like to test against the same regex engine that I'll use in production. If I'm writing Ruby, I'll use pry/irb or a tool like Rubular. If I'm writing Javascript, you'll find me in the closet with the barrel of a gun in my mouth... I mean, I'll test against my target browsers using their respective web inspector, or use a tool like RegExr.

An example of the differences in the engines, the Onigmo engine supports conditional sub-patterns:

Rubular: [http://rubular.com/r/zUwSsIi117](http://rubular.com/r/zUwSsIi117)

Regexr: [http://regexr.com/3b1vn](http://regexr.com/3b1vn)

As far as browsers go, they're actually pretty close most of the time. ECMA specifies regex (I think), so if you stick to the ECMA standard, you _should_ be fairly safe. As with anything in browser-land, you'll encounter edge-case inconsistencies that will bite you in the ass.

</comment></comment></comment><comment><USER15> I have been a regular user of this website for quite some time now. I like the UI and usability is great.

Also, [https://regex101.com](https://regex101.com) is very good alternative

</comment><comment><USER16> My favorite tool for quick regex definition to text extraction is [http://txt2re.com/](http://txt2re.com/)

Paste a sample line, mark the parts you like, it generates a piece of code to extract just those parts. Has saved me hours.

</comment><comment><USER17> RegExr is my go to regular expression playground. I've been using it for many years, back when it was on [http://gskinner.com/RegExr](http://gskinner.com/RegExr)

It's evolved a lot since then :)

</comment><comment><USER18> For anybody doing .NET development, RegexHero ([http://regexhero.net/tester](http://regexhero.net/tester)) is nice. It uses Silverlight though...

</comment><comment><USER19> Will be bookmarked alongside my other regex helpers.

One of my other favourites: [https://jex.im/regulex](https://jex.im/regulex) , a regex visualizer.

</comment><comment><USER20> [http://regexp.quaxio.com/](http://regexp.quaxio.com/) tries to act as a linter.

<comment><USER21> That's a great project by @amenghra and Facebook's Hack creator Julien Verlaguet!

Don't know if it made HN when it was released.

<comment><USER22> Oh wow, always cool to see stuff Julian has done!

</comment></comment></comment><comment><USER23> I've been programming for about two decades. I had composed three regexes before my first coffee and before seeing this article this morning. My problem: I _still_ don't have a good mnemonic to remember how magic differs grep, egrep, vim, awk, Perl, Python, etc. If that this site had modes and flavoured cheat-sheets I would live there!

<comment> cool-RR I use RegexBuddy, it has a shitload of different modes.

<comment><USER24> I love and miss RegexBuddy! If only they had a Mac/Linux version :( I've had thoughts about switching back to Windows while developing complex regular expressions.

<comment><USER25> Regexbuddy can be run on a Mac using Wine.

</comment></comment></comment></comment><comment><USER26>
      emacs

      M-x regexp-builder

</comment><comment><USER27> Sorry if this information is visible somewhere: Which dialect of regexp does RegExr "do?"

In the past, when I've looked for a good Internet RegEx test site, I've had trouble finding one that "does" the Java dialect.

</comment><comment><USER28> What I am missing is some kind of service to convert between different types of regexes. Like Java, Intellij Idea Search&Replace, vim, less, grep, egrep, sed. There are subtle (and sometimes not so subtle) differences between them which I always forgetting and have to trial&error a bit.

I wish there would be one single standard to regexes. Great tool but difficult to use because of many incompatible implementations.

</comment><comment><USER29> I've been using RegExr for years, it's the first place I go to when I have a tricky regular expression to put together. It works really well.

</comment><comment><USER30> My favorite is regulex[1] a visual explanation of regex

[1] [https://jex.im/regulex](https://jex.im/regulex)

<comment><USER31> [http://regexper.com/](http://regexper.com/) does the same thing.

I just wish there was something like this in reverse. Somewhere I can drag and drop the visual nodes and have it return the regex string to me.

</comment></comment><comment><USER32> This is awesome, but I like [https://regex101.com/](https://regex101.com/) more

</comment><comment><USER33> Suggestion: allow use of extended regexps too (I have a quick JS function to enable this, which you can regard as public domain: [http://blog.mackerron.com/2010/08/08/extended-multi-line- js-...](http://blog.mackerron.com/2010/08/08/extended-multi-line-js- regexps/)).

</comment><comment><USER34> Sites like this is great and all, but I wish they included some commonly used regexes. Like a list of 'good' regexs to validate phone numbers, emails and other common stuff.

It would actually be pretty cool to have a site like this except you could add the regex to a list, and then people could upvote the regexe depending on the quality of it.

<comment><USER34> ...and I just checked the community link. Way to go :-)

<comment><USER31> There's also [http://www.regxlib.com/](http://www.regxlib.com/)

</comment></comment></comment><comment><USER35> I've been looking for something like this on mac since I moved away from windows long time ago, no RegEx Buddy, such a great tool too. I think that I discovered regexr a year ago. This is such a great tool. Much appreciated work from @gskinner and community.

</comment><comment><USER36> I've tried a number of these and this is the one I've gotten along with best:

[http://jsregex.com/](http://jsregex.com/)

Simple, minimalist, takes up all available space in the viewport & also works offline if you save the page.

</comment><comment><USER37> I really like the regexp syntax coloring. What makes me still reach out for rubular.com, is actually the regexp cheat sheet on the bottom of the page. After 25 years, I still like to have a cheat sheet for regexp to remember all the swithces etc.

</comment><comment><USER38> Probably my favorite tool on the internet. One thing I wish it had was an implicit select option like grep -o since I frequently find myself using it to do interactive text manipulations for one offs.

</comment><comment><USER39> [http://refiddle.com/](http://refiddle.com/) is a similar service I've found useful.

</comment><comment><USER40> Is there a service that would allow one to enter positive matches and negative matches and it would then deduce a regex suggestion for that?

</comment><comment><USER41> My favorite for Python is still [http://www.pyregex.com/](http://www.pyregex.com/)

</comment><comment><USER42> This has been my go to regex testing site for years. Absolutely love it.

</comment><comment><USER43> Cool! These are the same guys behind CreateJS. Amazing work as well.

</comment><comment><USER44> this has been posted a few times, but is a great resource

</comment><comment><USER13> Author:

\- When did you begin this?

\- What front-end JS framework did you program this in?

\- How many visitors do you get per day?

<comment><USER45> You will probably get some info from the author's blog: [http://blog.gskinner.com/archives/2014/03/regexr-v2-build- te...](http://blog.gskinner.com/archives/2014/03/regexr-v2-build-test-learn- regular-expressions.html)</comment></comment>


How to Find Investors and Get Email Intros - <AUTHOR> https://www.atrium.co/blog/how-to-find-meet-investors/ <comment><USER2> I have no problems with cold emails. But if you're going to cold email a VC establish your credibility in the first 2-3 sentences. Crazy traction trumps everything (but don't oversell ornuse hyperbole) so lead with numbers if you have it. Absent that focus on your team's history of high achievement or other qualifying filters. If you're doing a fintech startup it's not sufficient to say I have 25 years of finance experience. You could have worked as a bank teller for all I know. Much better would be I worked at X-brand name and led a team of Y people and grew the business $millions. Name drop brand name companies like Google, McKinsey, or rank the company if it's less known (the second largest X.

The worst emails are cold emails from people saying they have some revolutionary technology but zero professional credibility no history of achievement or an ability to Marshall resources and the email is riddled with spelling mistakes. Next are emails from entrepreneurs with products so clearly out of your space that it's clear they were just mining linked in.

</comment><comment><USER3> Great advice! However, from my experience, I've found that networking events to be a complete waste of time -- I could be especially bad at it -- but I've found that the better and more long term way to build a network is to work with people. Be it joining a startup, going to work at a large tech company, collaborating on open-source, or even volunteering somewhere.

If you work at an early-stage startup you typically get to meet/interact with investors. And I did exactly that, the investors that I met at the first startup that I worked at when I emigrated to the U.S ended up investing in my company 4 years later.

<comment><USER4> If you talk to other founders, you'll probably find that all of them recommend both working with people (stronger friendships with a few people) and networking events (weaker friendships with a lot of people.)

<comment><USER3> I should say, I think that highly contextualized events, like say, "YC founders", or "Xoogler Founders", etc are useful. I think because a) there's a shared context and more probably shared interests b) there's frankly more signal-to-noise ratio, i.e. more likely than not people are worth knowing there.

But the paradox here is that you already need to have the relevant background to join such groups.

</comment></comment></comment><comment><USER5> Some years ago I attended a talk series about fundraising, and there were a lot of interesting topics covered, like financing types, valuations, how to handle meetings, how to negotiate, etc. When it came time for questions, I asked what probably sounded like an absolutely stupid question: "this has all been great advice, but how do I actually meet an investor in the first place?" The answer? "Use your network".

Coming from an engineering background, I really had no idea that fundraising required networking. I naively thought fundraising would be more like working with a bank. Like you walk into a clearly marked building and set an appointment, to get your arbitrary company funded. In reality, there are all these different VC types that fund different company types and stages, finding who VCs are is tricky (Crunchbase is your friend), and VC websites often don't have contact info (of course it would be useless anyway; you have to use your network). It's like a whole secret society nobody knows about.

After some years, I have a larger network, and can get meetings with most VCs. But holy moly that was not intuitive _at all_.

<comment><USER6> My biggest breakthrough, that I haven't used yet in practice, was when I realized that anyone with disposable income can be an angel investor. Got a friend who's loaded? Angel. Family member with more savings than they need? Angel. Friend just sold stock? Angel. Cousin got huge bonus? Angel.

</comment></comment><comment><USER7> Hello HN! Justin (the author) here. We launched our new Atrium blog as a resource to the startup community. Happy to answer any questions about VC intros here.

<comment><USER8> Curious if you can expand on the associates bit for when you _dont_ have an in with an associate.

Its always seemed that (generally speaking) most VCs with associates say you should talk to associates, and those seen as more "founder friendly" (i.e YC partners) or with no associates themselves say don't waste your time.

Also, if you get an intro to a partner and get pushed to an associate how do you handle it? Should you still take the meeting? Seems like that's a pretty strong negative initial signal but you don't want to burn bridges either.

<comment><USER7> Generally meeting with an associate means an extra gatekeeper to convince so that's why people suggest talking only with partners.

If you get pushed to an associate from a partner though it's hard to go back and demand the meeting with the partner. If you have limited options, you should take the associate meeting.

FWIW our first round for Justin.tv started with an associate conversation.

<comment><USER9> > meeting with an associate means an extra gatekeeper to convince

The associate is the one talking with all the other companies in your space and the related spaces, so if you cultivate good relationships with them then they're your eyes and ears on the industry.

</comment></comment></comment></comment><comment><USER10> It's an extroverts world. What are the best channels for introverts? How many potential start ups have never been funded because the founder(s) didn't have the networking skills that are natural to extroverts?

<comment><USER11> Introverts aren't as successful as extroverts in a CEO position that requires raising external capital and networking for customers. However introverts are often more successful in other roles (such as CTO), other types of companies (such as bootstrapped, low touch products), and other career types (eg mathematician).

<comment><USER12> Introverts can make good large company CEOs. Built to Last describes how the CEOs of companies who outperform the market over longer terms are more steady (hedgehogs) than flashy (foxes).

<comment><USER13> Yeah. Some people seem to assume "being an introvert" means being sentenced to social ineptitude. Most people can learn to overcome discomfort with certain experiences or activities. And with some effort, it's possible to even become good at such activities. Certainly, YMMV and not every introvert wants to, needs to or necessarily can pull it off.

If you're going to be CEO, either of a startup or a large co, you're probably broadly competent or hyper-competent in a handful of areas. Seems reasonable that at that level your ex/introvert tendencies are far from determinant.

<comment><USER14> "If you're going to be CEO, either of a startup or a large co, you're probably broadly competent or hyper-competent in a handful of areas."

Any particular reasoning behind this? Why would this particular specialty (abstract people management and capital allocation) be more likely to attract competent people than any other job specialty?

</comment></comment></comment></comment></comment><comment><USER15> Those are great tips! One thing I would love to see added is what the sweet spots are for each fund/investor. We all know who the social, saas or marketplace investors are. But within those groups, there are additional segmentations (eg: price-sensitive investors, those looking for a certain min ARR, those focused only on +$20B TAMs, etc). I realize that not every investor would like to be labeled to such a level of granularity, but many have very narrow windows of opportunity, and it's surprising that there's not more public info about their sweet spots.

<comment><USER7> This is a great idea for a crowd sourced database!

</comment></comment><comment><USER16> I think the one thing that begs repeating is how much YC is helpful in this process. It changes the fundraising dynamic for founders by allowing you to focus on product and growth and then creating an environment where investors come to you. It also provides you with an instant community of many founders who are happy to provide you with investor intros. Among other more significant benefits - YC is probably the best startup fundraising hack in the US (both for first time founders and repeat founders). I think this article is amazing advice but I really wish there would come a day when all early stage founders could just focus on making something their customers want and didn't need advice on how to break into the startup investment scene. I think this barrier prevents many great founders from getting started and many important problems from being solved.

</comment><comment><USER17> Double opt-in should be always the etiquette for introductions! We built [https://intrologic.com](https://intrologic.com), connect your email metadata and linkedin connections file, invite your friends and connectors and we provide you a searchable interface to request for intros to potential investors or qualified leads. Sign up: [https://intrologic.com/start](https://intrologic.com/start). Founder here.

</comment><comment><USER18> the email template is $$$</comment>


Startup Lessons from StartupRiot - <AUTHOR> http://www.simplifyingsoftware.com/2012/02/startup-lessons-from-startupriot.html

<comment><USER2> Great post, Harris. Glad you liked the event. I had a blast as well. Were you still around for the last set? I demoed Spindows.com (the enterprise video speed-networking platform). Would love your honest thoughts on it.</comment>


ZStack v1.1 release: Infrastructure-as-a-service software - <AUTHOR> http://zstack.org/cn/blog/v1.1.html <comment><USER2> Home: [http://zstack.org/](http://zstack.org/)

 _ZStack is open source IaaS(infrastructure as a service) software aiming to automate datacenters, managing resources of compute, storage, and networking all by APIs._

</comment><comment><USER3> Does anyone have experience with this? How does it compare to e.g. OpenStack or CloudStack?

<comment><AUTHOR> I am the author of ZStack, a former core developer of CloudStack since 2010 Cloud.com, and a close OpenStack watcher since 2011. Given ZStack, Openstack, CloudStack, Eucalyptus are all IaaS software, they were very similar speaking of functions. However, some features make ZStack specific:

1\. Huge Scale

Because of full-async architecture, stateless services and lock-free architecture, ZStack can handle huge concurrent APIs very fast. In our simulator test, ZStack installed in a virtual machine with 8CPU, 8G memory can serve 30K concurrent APIs. And an IBM IT guy tested ZStack on 4 physical machines creating 1000 VM concurrently, all tasks completed successfully in 4 minutes. This is the best performance data I have been seen so far in IaaS area.

2\. Seamless Upgrade

Upgrade is a headache problem that users have been suffered for a long time. ZStack is the first IaaS really implementing seamless upgrade, all you need is to run a singe command, for example:

          bash zstack-installer-1.1.0.bin -u

You don't have to worry about agents on host or in virtual appliances, ZStack itself takes care all of them. The upgrade takes 5 minutes normally. From the initial version 0.6 to the current version 1.1, our users have done the upgrade thousands of times all by themselves, no even a single failure. If you have ever upgraded an Openstack deployment, you know how hard this could be.

3\. Full APIs

Tasks in ZStack are all delivered through APIs. You don't have to manually configure a service or install an agent. For example, to add a host, you can just call the API AddKvmHost with its IP and SSH credential, ZStack will automatically configure the system, install dependent packages(e.g. libvirt), and deploy own kvm-agent. Openstack only has APIs for manipulating VMs, so Mirantis releases a product Fuel to solve this problem. However, given Openstack was not designed in the way that makes everything APIable, it's hard to build a reliable product automating everything.

ZStack's automation is built up on Ansible that is a famous configuration management tool. We directly use Ansbile SDK to customize the deployment process for every ZStack agent, and hide them from end users. So you don't have to care about details of deployment, all you need is to install the single ZStack binary and play with the web UI or CLI, we takes care the rest of the world!

4\. Full Query API

Companies which wants to do Devops on the IaaS often encounter a problem that there is no API to search resources, so they have to bypass the software and directly access the database. ZStack solves this problem by query APIs, you can do SQL-like queries including table-join at API level. For example:

        QueryHost fields=name,uuid,managementIp hypervisorType=KVM vmInstance.allVolumes.size>=549755813888000 vmInstance.state=Running start=0 limit=10

Developers don't need to write any code for queries; they just need to create a database table and define a query API in two lines of code, ZStack's query engine will interpret the API and generate proper SQL statements.

With the query API, enterprises can build sophisticated UI similar to outlook and jira, which generate views defined by query.

5\. Light-weight IaaS

ZStack is light-weight IaaS that can be easily installed on a single physical machine even virtual machine. Many of our users use two machines to setup a HA cluster where computing, storage and control nodes are converged. This can help small businesses build their private cloud, without purchasing many hardware just for deploying a control panel.

If you think OpenStack is unnecessary complexity for your cloud, I recommend you to try out ZStack.

</comment></comment><comment><USER4> How does this compare with eucalyptus, the open source AWS clone: [https://github.com/eucalyptus/eucalyptus](https://github.com/eucalyptus/eucalyptus) ?

<comment><USER5> A more interesting question is how it compares to OpenStack, no?

<comment><USER6> Blog post on motivation for creating an alternate to OpenStack [http://zstack.org/blog/why-zstack.html](http://zstack.org/blog/why- zstack.html)</comment></comment></comment>


Introducing Jib — Build Java Docker images better - <AUTHOR> https://cloudplatform.googleblog.com/2018/07/introducing-jib-build-java-docker-images-better.html <comment><USER2> I'm a Docker noob and I haven't shipped Java in ten years, and I find that this article leaves the main question unanswered: _what happened to just building a JAR?_

When I read that sentence, I assumed that it must be something about controlling the JVM parameters and version, or the ability to include certain system tools or imagemagick type of CLI thingos, but then as the article goes on, I see none of that. None of the things that, to my uninitiated mind, give Docker an edge over building a plain old JAR.

So why? Why is it necessary / a good idea to Dockerize a Java app? Can anyone help me out?

<comment><USER3> There are really a host of reasons why it's a good idea. Off the top of my head here are three that I think justify the weight:

1\. A Jar includes your app, but not your runtime or your applications native deps. Docker containers let you specify a whole lot more about your image that goes beyond the language specific application package.

2\. You can use the same tooling and infrastructure for managing your executable binary artifacts across all the languages used in your org.

3\. You can take advantage of cluster schedulers like K8s.

<comment><USER4> Point 1 is taken care by fat jars and jlink.

<comment><AUTHOR> While technically correct the maven-jlink-plugin is in alpha and I've not yet seen any application packaged this way. If you're aware of any open-source project doing this I would be very interested :)

<comment><USER5> With the planned removal of java webstart from java 11 onwards this september, you can expect jlink to become much more relevant.

</comment></comment></comment></comment></comment><comment><USER6> Here is my "initial" sbt implementation: [https://github.com/schmitch/sbt- jib](https://github.com/schmitch/sbt-jib)

(Should be easier to do after: [https://github.com/GoogleContainerTools/jib/issues/337](https://github.com/GoogleContainerTools/jib/issues/337))

It also still misses some important things like that not all resources will be put into the resources layer and also that the resources should be deduplicated, if any.

Edit: thanks google for this awesome library! With this library you prolly loose some money!

</comment><comment><USER7> Yay! Good steps (in the Java ecosystem at least) to bring containers closer to their potential.

Docker is the best example I know of how " _worse is better_ " can lead to absurdly bad local maxima. Docker solves the most shallow and most obvious problems of software deployment: How to package all dependencies in one big ball of mud.

Instead of declaring dependencies explicitly (with acceptable version ranges like maven, bundler, even nvm can do for ages) we get the equivalent of a bash script (Dockerfile) that is impossible to parse automatically and encourages volatile external dependencies (`curl [http://mirror.com/current_version.sh](http://mirror.com/current_version.sh) | bash`)

Instead of slim, reproducible build descriptions that could reference single files or packages via hash sums (ala `packages.lockfile`) we get fat filesystems with the caching granularity of snapshots. But why care, developers have multi terabyte SSDs and gigabit network connections by now, right?

Instead of being able to propagate security updates down to each package (/container), we have a filesystem snapshot caching, where cache invalidation is for all intends and purposes impossible. But cache invalidation is hard, so how could you blame docker?

And I get why Dockerfiles are so seductive: They are damn easy. You can build your first docker image in minutes. But also docker doesn't help you to solve any of the deeper problems for you. E.g. you better figure out how to invalidate your cached image layers yourself when packages get security updates. Or just rebuild everything all the time, but there goes your performance and maybe some of those pesky external dependencies are no longer available. Want to internalize those? Build that yourself, too, docker can't help you there, because it is too damn simple.

So, Horray to Jib! All the work that has already gone into Maven to solve the deeper problems (e.g. internalizing external dependencies with Nexus) can be repurposed to build container images. Let's hope we get more of that "more complex but better" sanity.

</comment><comment><USER8> Seems like a good idea for new project. The article says "You don't have to create a Dockerfile" but honestly, who does?

There are a ton of Gradle/SBT/Maven plugins that build your container for you. Most call your Docker daemon API directly, copy in all your jars and write a startup script. Some generate a Dockerfile, but they stick it in your build directly and you never touch it directly.

The advantage is not needing a Docker daemon. That is pretty nice. However I already need a daemon in our Jenkins pipeline and a lot of my unit tests use the Scala testcontainers framework (so I can run tests against a real MySQL or Postgres DB, which is way nicer than using mocks or H2).

So it is nice, but chances are, we're already running container daemons everywhere already.

Plus I'm sure for this to be really useful, we'll need ECR plugins as well (which will probably need to be 3rd party because I don't see Google supporting AWS officially).

I wouldn't move to this if I was on something that worked. That previous article about the team going back to maven after a gradle migration is kinda in that same view: with a new project you can make it clean, but your current project is probably so customized around your workflow that unless you can make a case for a really bad pain point it will solve, it's probably not worth it.

A good pain point I think this would solve is if your CI doesn't have access to a Docker daemon at all (for security or you're using a hosted solution or whatever) and you want to be able to build containers and publish them in your CI.

<comment><USER9> There's two things here.

The first is layering. A goal is smarter layering without a Dockerfile. A dependency-management tool gives fairly good insight into how to arrange layers to improve cacheability and reduce layer churn.

The second is security. Going without a daemon socket is more than "pretty nice", it is a _massive_ security win. Docker daemons have a lot of privileged access and a wide API. Having that entire massive attack surface lying around to write some tarballs and a JSON file on your behalf doesn't make a great deal of sense.

These both become more valuable at large scales, which is why it makes sense for Google folks to have developed it.

<comment><USER10> Agreed re: both of these wins.

On the security front, would be ideal if these resulting containers ran as non-root. Hopefully that will come soon.

</comment></comment></comment><comment><USER11> It'll be really interesting to see where this goes. We currently use Fabric8's Docker Maven Plugin ([https://dmp.fabric8.io/](https://dmp.fabric8.io/)) for our Java-based containers. It's a little verbose but works really well- it allows us to run our integration tests directly against the final container images (+ any container dependencies) as part of the standard Maven build.

<comment><USER12> I wish fabric8 had Gradle support.

This ticket implies that it isn't "build tool agnostic" ([https://github.com/fabric8io/fabric8-maven- plugin/issues/609...](https://github.com/fabric8io/fabric8-maven- plugin/issues/609#issuecomment-297363332)) and I found a few github repos that are "gradle plugins" for Fabric8 but they only had a few stars or were out of date.

</comment></comment><comment><USER13> Maybe someone can help me out on a question I've not got a clear answer on: is it better to build your artefact (jar file in this case) and put that in the docker image, or is it better to put everything you need in the image (source files, dependencies etc) then build the artefact from within the container?

Seems to me like the first approach (compile outside then put artefact in container) is the most sane/sensible approach and the one used here in Jib, but I have seen people advocating the build-in-container approach as better (self-contained, repeatable and so on).

Any benefits to the build-in-container approach that are compelling?

<comment><USER14> Docker recently has support for multi stage builds. So you can use one Dockerfile to define how to build your image (produce your jar and necessary other resources) and then copy them into a fresh container running off a more lightweight image that might not contain all the intermediates and your build tools.

[https://docs.docker.com/develop/develop-images/multistage- bu...](https://docs.docker.com/develop/develop-images/multistage-build/#use- multi-stage-builds)

<comment><USER15> Multi-stage builds is definitely my preferred method of building stuff, but the problem I've found is that caching dependencies is bit of a pain, either you need to do some tricks with volumes or your builds will be very slow.

<comment><USER16> At work, I setup the build system to use Apache Archiva to cache Java dependencies, along with other services like apt-cacher, devpi, and squid, for Debian, Python, and general HTTP caching, respectively. We build all of our images atop the "bitnami/minideb" base, and split the Dockerfiles into "partials" that source a dynamic parent image via a build argument. For example, the partial that sets up Debian package and HTTP caching:

        ARG base
        FROM ${base}
        ARG apt_cacher_host
        ARG http_proxy
        ARG https_proxy
        ARG no_proxy
        ENV HTTP_PROXY="${http_proxy}"
        ENV HTTPS_PROXY="${https_proxy}"
        ENV NO_PROXY="${no_proxy}"
        ENV http_proxy="${http_proxy}"
        ENV https_proxy="${https_proxy}"
        ENV no_proxy="${no_proxy}"
        RUN set -ex; \
            if [ ! -z "${apt_cacher_host}" ]; then \
                echo "Acquire::http::Proxy \"${apt_cacher_host}\";Acquire::https::Proxy \"false\";" >/etc/apt/apt.conf.d/01proxy; \
            fi; \

For Java, another partial creates a Maven settings file with the Apache Archiva URL:

        ARG base
        FROM ${base}
        ARG maven_mirror
        COPY devops/image-partials/java-artifacts/settings.xml /tmp/settings.xml
        RUN set -ex; \
            env; \
            if [ ! -z "${maven_mirror}" ]; then \
                sed -r "s!%%MAVEN_MIRROR%%!${maven_mirror}!g;" /tmp/settings.xml >/usr/share/maven/conf/settings.xml; \
            fi;

The important part of settings.xml is this section:

        <mirrors>
            <mirror>
                <id>archiva.default</id>
                <url>%%MAVEN_MIRROR%%</url>
                <mirrorOf>external:*</mirrorOf>
            </mirror>
        </mirrors>

And voila, Maven will go through Archiva for all its dependencies, which are transparently cached so that subsequent builds don't need to re-download everything again.

</comment></comment></comment></comment><comment><USER17> Maybe I am old school. But I kinda like a WAR-file, run/deployment via a maven plugin and a simple servlet container (like Tomcat). If you run a pure Java stack why not keep to this stuff that has been around for ages?

<comment><USER18> Containers give control over the application's JRE version (without making a self-extracting executable).

<comment><USER17> Sure but in practice that would change very rarely.

For what I am working on a deployment takes a couple of seconds including controlled shutdown and startup of the application.

I don't know how fast docker/jib would be but I am imagining this would be a somewhat heavier setup?

<comment><USER19> Not having to install and manage a tomcat server is pretty nice. There is "embedded" tomcat so you can just run `java -jar my-app.jar` but then you still have to worry about installing and managing the JVM plus whatever file- system resources like logging locations etc.

> [JRE version] would change very rarely.

It's optimizing for setting up new machines and having everything about how to run an application contained within that application itself rather than relying on sysadmins to `yum install` things or whatever. Plus with docker you always run the same version in prod that you do in dev (and on your local machine) unless you intentionally do something else.

> I don't know how fast docker/jib would be but I am imagining this would be a > somewhat heavier setup?

Not really - a layered docker image may have tomcat as a base layer and then the app jars etc layered atop. Deployment is just downloading a new layer which wouldn't really be any overhead atop of just the jars.

<comment><USER17> I am curious about startup / deployment times?

When I a deploy WAR-file it, it is fairly small (just app + dependencies), and startup / shutdown is well-defined and happens fast, allowing me to update an application with just a few seconds downtime. But here - how fast would an update be? How much downtime? Does it reinstall the os, the vm, the app, are the shutdown / startup operation well defined or does the process just get killed?

Wouldn't it take quiet a bit of work just to match what you get out of the box in a traditional setup?

<comment><USER20> You would bring up a 2nd container with the new code, map the traffic to this container, and once you are sure it is good, trash the old container.

If there is a problem with the new code, just point the traffic back to the working container and kill the new container.

<comment><USER17> So it is so slow you have two spin up a second node :-D

</comment></comment></comment></comment></comment></comment></comment><comment><USER21> This seems pretty neat if you have the infrastructure already, removes a lot of the busy work around creating docker images etc, and from the looks of the instructions it looks like you don't even need Docker installed to create the image - which is great for CI!

</comment><comment><USER22> Someone asked me if I used Google's Skaffold (save+push to kubernetes), and I giggled and told we mainly use Java and Spring even boot takes more than 10 seconds and building also takes around 10 seconds, so if you do not have .m2 caches, it would take much more time.

Dependency caches and already built components, in all languages (Go, Java, Nodejs) is always a problem for us in Docker in our CI/CD, glad to see such solutions coming up

<comment><USER23> Often you can just mount a persistent volume where the cache should go.

<comment><USER22> What do you do when they are shared and remote?

</comment></comment></comment><comment><USER24> I started to make something similar with Node, since I wanted to use Node to make containers rather than shell scripts (I don't think learning shell scripts should be a prereq for NoOps). Unfortunately I got distracted, before I eliminated the need for a Dockerfile (it had a wrapper Dockerfile that ran npm scripts) [https://github.com/diodejs/dev/blob/master/Dockerfile](https://github.com/diodejs/dev/blob/master/Dockerfile)

It's based on a plain alpine container, with the idea that you can run `apk remove node` when you're done to clean it up if you don't need node once the container is built.

A lot of people are missing that this is really about replacing shell scripts with Maven or Gradle. You can still build a fat JAR.

<comment><USER9> Google have also done work on the more general idea of "read dependencies to layout containers", under the title FTL. I would give you a link but it is a maddeningly ungoogleable name.

</comment></comment><comment><USER25> How does this compare to sbt-native-packager docker integration?

<comment><USER26> sbt-native-packager doesn't do dependencies as separate layers, so the image has a big fat layer with all your jars.

</comment></comment><comment><USER27> Docker works wonders if you don't have a functioning app server or something equivalent. If you don't have the possibility of deploying to an already functioning cluster, use docker. If you have an environment where you can't "run everywhere" use docker. However docker _is_ just something to handle environments. Not applications.

</comment><comment><USER28> If you really want to explore why running a JVM in a Docker container makes a lot of sense, try running a modded Minecraft server with and without a container for a few weeks.

Another commenter in the thread mentioned that "Docker eliminates wishful thinking." Getting that first modded Minecraft server operational will drive that home.

</comment><comment><USER29> Looking forward to Microsoft investing some more in this area with Core. Creating a new Core project offers to add Docker support which is pretty decent out of the box but it's pretty much hands off after that point and you have to do everything yourself from there.

</comment><comment><USER30> Java isn't an ideal fit for containerization or horizontal scaling by nature, but if you're stuck with it and really want to avoid using anything other than Java ecosystem tooling, this seems like a timesaver.

<comment><USER31> Why would Java not be an ideal fit for containerization (why would any runtime not be)? Also, given you don't have to pack everything into one VM (can have many nodes, VMs, load balanced, whatever)...what makes Java particularly bad for horizontal scaling?

<comment><USER32> Yea I don't understand the original comment... however it is true Java isn't (or at least wasn't until recently) ideal for containerization, since the JVM would not obey things like cgroup limits for memory and CPU. This was fixed in Java 9 and backported to the Java 8 (update 131) however there are still potential issues regarding CPU isolation that are not trivially solved without some explicit configuration.

For a good overview, see: [https://mesosphere.com/blog/java- container/](https://mesosphere.com/blog/java-container/)

</comment></comment></comment><comment><USER33> I ended up leveraging multi-stage building with Docker and have a gradle image as my builder image, build the jar, and copy that to the image that is going to get deployed.

</comment><comment><USER34> U can help with dockerizing Java application and running it in nomad cluster

<comment><USER34> I can help</comment></comment>


End to End with AngularJS - <AUTHOR> http://www.youtube.com/watch?v=hqAyiqUs93c

<comment><AUTHOR> This is an extension of my screencast "Intro to Angular JS" [1] that focuses more on intermediate/advanced topics and walks through creating a working web application on top of the Laravel 4 Web Application Framework. Things you can expect to learn by watching the screencast:

$http

$rootScope

taking the AuthenticationService [2] we built earlier end-to-end

creating a FlashService for displaying alerts to users

access control for client-side routes with $rootScope and $routeProvider

$httpProvider.responseInterceptors and logging out users automatically if serverside sessions expire

$routeProvider.resolve property and making view rendering data dependent

laravel 4 migrations, controllers, models, and authentication

[1] - <http://www.youtube.com/watch?v=8ILQOFAgaXE>

[2] - [https://github.com/davemo/intro-to- angularjs/blob/master/app...](https://github.com/davemo/intro-to- angularjs/blob/master/app/js/app.js#L19)</comment>


Show HN: 60 Minutes Chat – Anonymously chat in self-destructing chatrooms nearby - <AUTHOR> https://play.google.com/store/apps/details?id=com.hour.chat <comment><USER2> Is it anonymous?

Permissions:

Identity Uses one or more of: accounts on the device, profile data

Contacts/Calendar Uses one or more of: calendar, contact information

Location Uses the device's location

<comment><AUTHOR> Ok, it seems that the update hasn't gone through yet, where it only asks for location now. Should be through soon.

<comment><USER3> It works for me, only requesting location.

</comment></comment></comment><comment><USER4> While perhaps an interesting mechanic in larger cities, the core feature of this product will ensure minimal adoption in rural towns like mine. User will install, see there are no active chats, create one, never get a response, and uninstall.

Perhaps add the ability to expand your area?

<comment><USER5> It might make sense to define the area based on population density rather than just geography.

<comment><AUTHOR> That's an excellent idea, I was thinking about how to fix this problem. I think starting with a radius of 5 miles and increasing it until users can see the chatrooms from the closest 100 people would solve all that.

<comment><USER5> Yes, but you probably want some cut off. It might be better to see a shorter list of people who are reasonably close rather than 100 people who might not even be in the same country.

<comment><AUTHOR> Hmm, I see your point, but isn't it better to have content on the app with people a bit farther away instead of "no content of people close-by."

<comment><USER5> It depends really on what the purpose of your app is. I would normalise your data somehow against a population map, so distance in sparsely populated areas is weighted differently to dense urban areas.

</comment></comment></comment></comment></comment></comment><comment><USER6> I'm ambivalent on the name, though I do like that the name says what it does without any silly made-up gibbrish name.

<comment><USER7> Reminds me of "60 Minutes" the long-running television news program. If I didn't know better, I would assume this was an app for discussing recent 60 Minutes stories.

Maybe I'm just old, though.

<comment><USER6> Maybe that's the hidden motivator in my brain. Now I can't not think of 60 minutes (the program) when I see this name.

</comment></comment></comment><comment><USER8> I've been using this for around 10 minutes now and it seems fairly buggy, the main ones I've hit are:

* Messages appear in the wrong conversation, then move back to the correct one on close/open. * I get notified about new chats that then don't appear in the list

<comment><AUTHOR> Thanks, working on it! Didn't expect that to directly take to be honest.

</comment></comment><comment><USER9> Interested in collabing with you on this. I had the same idea and vision.

any way to contact you

<comment><AUTHOR> Sure, iOS and possibly also Android developer would be helpful! Shoot me an email, it's in my bio.

</comment></comment><comment><AUTHOR> Some stats two hours after submission if someone is interested:

\- 92 new users

\- 88 chatrooms were opened

\- 14 users from London, 10 Amsterdam, 8 Berlin, 8 New York, 8 Chicago, 6 Toronto. It seems like because it's so early, mostly Europe has seen it so far.

<comment><USER10> SF is just waking up so that is probably why you don't see more.

</comment></comment><comment><USER11> Hasn't this 'chat to people near you' been done to death already? I was thinking of doing an app like this a few years ago, but discovered that there were many similar apps.

<comment><AUTHOR> In fact, there was Popcorn Messaging, which is anonymous chat within 1 mi radius. I loved the idea and checked the app quite often. However, the chats on there were almost never relevant to me, because there was no curation at all and this way, there was almost no way to communicate with people on there or to get an answer on anything.

So, I thought what if you add topics to the app, so that if I have a specific question, everyone in the area would get alerted by it and I could have my answer within just a few minutes. Giving the chatrooms a self-destruct timer would make them even more ephemeral. This way, the user knows that content on 60 Minutes is relevant and current at all times.

</comment></comment><comment><USER12> App v1.0.1 keeps asking me turn on the GPS to start a chat. My GPS is on and Google Maps doesn't have an issue with it. Nexus S running 4.4.4

</comment><comment><USER13> I would use this. I could see it really catching on.

</comment><comment><USER14> No iOS version in case anybody is curious.

<comment><USER15> That seems stupid. This is an app that needs all the network effect it can get.

<comment><USER16> What's stupid about starting with the biggest platform?

</comment></comment></comment><comment><USER17> I downloaded it on my Galaxy S3 and it kept crashing. Cool idea, but there are definitely some bugs in it.

</comment><comment><USER18> Stop cloning Yo's UI

<comment><USER2> It's from the same company.

Edit: oh no it isn't! (thanks!)

<comment><USER19> The app you see under "more from developer" isn't the original Yo.</comment></comment></comment>


Show HN: Omnimemory – Simple multi-device flashcards - <AUTHOR> https://omnimemory.com

<comment><USER2> Looks great on mobile. I tried to look at the HTML source code to check if you where using front-end framework but I wasn't able to find any.

How did you build it?

<comment><AUTHOR> ClojureScript with Enfocus ([https://github.com/ckirkendall/enfocus/](https://github.com/ckirkendall/enfocus/)) in the front-end, and Clojure with Enlive ([https://github.com/cgrand/enlive](https://github.com/cgrand/enlive)) in the backend. It's not a SPA. I started it a while ago, before React/Om. If it were now I would write it as a SPA and use some React wrapper, probably Rum ([https://github.com/tonsky/rum](https://github.com/tonsky/rum)).

As for HTML/CSS, no framework at all. I'm interested in simple, minimalistic, innovative design, and I don't think frameworks help to achieve that.</comment></comment>


Ask HN: When it comes to developer blogs, what are your pet peeves? - <AUTHOR> I for one really enjoy reading other developers' blogs, and if it's really good I'll often binge read all their posts. I myself have a small personal blog that I've been working on, and am wondering what habits, or design traits should be avoided? I get the feeling we often copy others without knowing whether it's a good practice or bad habit.<p>Personally my list of pet peeves are:<p>- No code syntax highlighting. If code is the main focus of the blog, then why not make it look nice?<p>- (Stolen from Jeff Atwood) Blogging about blogging. It builds up junk content quickly that diminishes overall quality.<p>- Having an always visible side bar with your profile picture staring at the reader. <comment><USER2> My pet peeve about developer blogs is people who have only been using a language (or framework, or whatever) for a couple of weeks writing about their experiences with it. Sorry, but I'll find your experiences interesting once you've shipped a significant chunk of code in that language, let's say after half a year of full-time experience. If I want to know what it's like to write a toy application in that language, I'll just do it myself, not read a blog post about it written by someone with only a superficial knowledge of it.

> Blogging about blogging

That's something we can agree on. If a "developer blog" has an article called "Why Every Developer Must Have a Blog", it's a strong signal of low quality content - it tells me that the author apparently likes to make sweeping generalizations without thinking about what they're saying. Either that, or they have nothing interesting to say about more substantive topics.

In fact, I suspect that blog posts like "Here's What I Have To Say About Rust After Using It For Two Weeks" are usually written by people who have just read an article about "Why Every Developer Must Have a Blog" and are now convinced that they desperately need their own blog, despite having nothing interesting to say.

> No code syntax highlighting

People have different tastes. Personally, I find it very distracting to be looking at code in a rainbow of different colors, with tokens like identifiers, keywords, numbers and strings all screaming for attention due to their unique coloring. All these types of tokens can be easily identified without syntax coloring if you're familiar with the syntax of just about any programming language. (The only syntax highlighting I ever use is to make comments slightly less emphasized than code.)

> Having an always visible side bar with your profile picture staring at the > reader

Another thing we can agree on. What someone looks like has no bearing on how interesting their writing is, and I find it creepy to have someone staring at me from the screen while I'm trying to read.</comment>


Ask HN: How do you deal with atomicity in microservice environments? - <AUTHOR> We run a small SaaS where users are able to create accounts, submit billing information and upload/call ML artefacts.
In order to not reinvent the wheel we use external services where possible: Auth0 for authentication, Stripe for handling billing, etc. For this question, I am considering this a 'microservices' architecture. I am aware that this definition will spark its own discussion, but I believe that the problem generalises to a lot of the other (better, more complete, etc.) microservice definitions. So please, bear with me.
Now, in the lifecycle of a customer (createAccount, addBilling, deleteAccount, ...) at various points we expect operations to occur atomically. By which I mean (simplified) that upon creating a new account, I also need to ensure a customer is created in Stripe as well as register the user in Auth0 - but if either of these subtasks fail, the operation (createAccount) should fail completely and in fact 'undo' any state changes already performed. If not, I risk high-impact bugs such as double charging customers.
Now, in a 'conventional' setup (without external services), I would resolve a lot of this by ensuring transactional operations on a single source-of-truth database. I understand that 'idempotency' comes up a lot here, but whichever way I try to apply that here - it always seems to explode in a (fragile/brittle) spaghetti of calls, error handling and subsequent calls.
Surely this has been resolved by now, but I'm having a hard time finding any good resources on how to approach this in an elegant manner. Concretely:
Do you recognise the problem of atomicity in microservices architecture?
And,
How do you deal with guaranteeing this atomicity in your microservices? <comment><USER2> Having built similar applications in microservice environments, I think there are usually simpler answers than distributed transactions. And if you do need distributed transactions, this is often a sign that your service boundaries are too granular.

In fact, since the services you're describing don't know about each other, distributed transactions aren't an option.

I think the only solution to this problem is idempotency. Idempotency is a distributed systems swiss army knife—you can tackle 90% of use cases by combining retries and idempotency and never have to worry about ACID. Yes, it adds complexity. No, you don't have a choice.

I'm also not sure why this requires a lot of complexity. Can you explain how you're implementing idempotency? The simplest approach is to initialize an idempotency key on the browser side which you thread across your call graph. Stripe has built in support for idempotency keys so in that case, no additional logic is required. For providers without idempotency support, you'll need a way to track idempotency keys atomically, but this is usually trivial to implement. When a particular provider fails, you can ask users to retry.

* If you need a particular operation to succeed only if another succeeds (creating a stripe charge, for example), make sure that it runs after its dependencies.

* If you don't like the idea of forcing users to retry, you can ensure "eventual consistency" using a durable queue + idempotency.

I'm not a fan of HN comments that trivialize problems, but if you have to build complex distributed systems machinery to solve the problem you're describing, I feel strongly that something's going wrong.

<comment><USER2> Also, I think the answers you're getting keep telling you to build distributed transactions because

a.) they didn't read your post and are overindexing on "microservices" b.) this isn't an atomicity problem, it's a workflow problem. When people say atomicity, they're usually referring to operations over data. In your case, it sounds like you need a way to coordinate execution of side-effectful operations (like creating a charge).

<comment><USER3> but, when one starts talking about idempotence and retries the first thing that comes to mind is these are just user mediated two phases commits, where an error dialog and user interaction drive the phases instead of a distributed transaction system, by which point one can just cut the middleman and build the thing out of tested and robust components

<comment><USER2> What middleman do you want to cut out? My proposal doesn't add any dependencies. It's also not possible to prevent duplicate charges if a user POSTs a form twice without idempotency keys, so idempotency is necessary.

I'm really not sure what you're actually proposing?

<comment><USER3> the user doing the retries

</comment></comment></comment></comment></comment><comment><USER4> You often don't need or want cross service atomicity, just eventual consistency. Each microservice should be an idempotent state-machine where it expects to have atomic commits to it's own state but never expects to be able to conduct a transaction across the service boundary. However, services can conduct local transactions on their own state joined against a read-only cached copy of another service's state - you can implement this with an event bus or a shared caching tier. This can allow you to avoid writing your own joining logic and use standard ORMs. Ensuring the queues are flowing and retries happen is very important though, you need to monitor queue lengths and job errors to ensure the eventual part of eventual consistency is happening.

For this particular example createAccount would create a local commit with a state of CREATING, returns an account_id and asynchronously creates jobs to complete the billing, the auth, whatever. You then have a job that is polling in the background to move the account to CREATED once all or enough of the dependencies are successful(i.e you may have a slow third party provider you don't want to block on). Your front end polls the state of the account and displays a pretty animation to distract the user while you do the work.

<comment><AUTHOR> Thanks. From my (limited) understanding this sounds a lot like the Sagas that have been suggested by others - does that match your intention?

</comment></comment><comment><USER5> "Sagas", or distributed transactions, are what you're looking for. These are APIs/functions/methods that know how to complete every step of your atomic operation and how to roll it back if any step fails. They more or less recreate what would have been a single database transaction pre-microservice.

<comment><AUTHOR> That's it! Not sure how I never stumbled upon this. Thanks!

<comment><USER6> Came here to say same thing. Saga pattern is the way to go.

Also, suggest you to carefully think about transaction boundaries, if possible, prefer eventual consistency over transactions.

</comment></comment></comment><comment><USER7> The real business world is not atomic. The idea is to keep track of things that you've done, and do compensating things to roll their effect back if something goes wrong. See the Saga pattern for an example. I also found Gregor Hohpe's blog post [0] titled "Starbucks Does Not Use Two-Phase Commit" very informative.

[0] [https://www.enterpriseintegrationpatterns.com/ramblings/18_s...](https://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html)

<comment><USER8> good read. ... thanks

</comment></comment><comment><USER9> Not everything that uses lots of services needs to be a classical "microservice" architecture, where every service can call every other service.

You can have a component that coordinates workflows (can be a different component for each workflow, or can be one central component, depending on your need to scale vs. simplicity).

In the OpenStack project, they developed TaskFlow[0] for that. It allows you to build graphs of tasks, handles parallelization, persistence of meta information (if desired) and, important for your use case, rollback functions in case of errors.

[0]: [https://docs.openstack.org/taskflow/latest/](https://docs.openstack.org/taskflow/latest/)

</comment><comment><USER10> "Designing Data-Intensive Applications" by Martin Kleppmann touches on this subject: [http://dataintensive.net](http://dataintensive.net)

</comment><comment><USER11> I know two not-so-complex ways for dealing with this:

1\. Use a persistent queue where you store what needs to be done, this allows you to ensure than an operation will eventually succeed by a leveraging the powers of the queue, you'll need to keep track of the stages where the jobs failed in order to not repeat operations.

2\. Rely on the clients retrying and use idempotency, there is a nice and very detailed blog[0] about it, this works very well with your microservices but most external services won't have idempotency and you'll need to plan on how to deal with those in order to emulate idempotency, sometimes the queue helps.

[0]: [https://brandur.org/idempotency-keys](https://brandur.org/idempotency- keys)

<comment><AUTHOR> thanks, useful resource!

</comment></comment><comment><USER12> Just don't bother. At the scale you're working at, if something tries to run and, e.g. The user doesn't exist, just throw an exception, email the team for a manual fix. If(if!) it becomes too common, throw in a retry or two.

You have better things to be doing in a startup vs distributed transactions (and honestly, microservices...)

</comment><comment><USER13> This is a hard problem to tackle.

An obvious approach is 2-phase commit or N-phase commit. 2PC and NPC are generally not recommended because it sacrifices performance too much.

* Pros: It is more like a transaction so that you don't have to write rollback logic.

* Cons: It seriously sacrifices system availability since the distributed transaction happens across networks.

A commonly recommended approach is Saga, it's basically compensation.

* Pros: Does not sacrifices system availability since it's an asynchronous/optimal design.

* Cons: Have to write a lot of compensation logic and call them correctly.

* Cons: There are a lot of operations that cannot be compensated. These operations should be arranged in the last steps.

* Cons: What happens if compensation fails?

* Cons: It's eventual consistency, it's not strong atomicity.

I have to admit, I don't try to tackle this problem unless it's really important for the business in a microservices environment.

If your business requires atomicity in most of the places, it's highly recommended to have a carefully designed monolith so you can easily benefit from RDBMS, with your domains modeled in different modules instead of services.

<comment><AUTHOR> Thanks, really appreciate the pros and cons here. To be clear, and I understand the confusion: I'm actually building more or less a monolith with a RDBMS to encapsulate most of the business logic of my problem domain.

However, for various parts of my application that seem high-complexity, high- impact and non-competetive edge (such as authentication and credit card handling) I want to outsource to external services (Auth0 and Stripe). This brings with it the challenge of managing state, and consistency across various external services (on top of the state I manage internally).

The reason microservices is mentioned in the question, is because I believe these problems generalise from my specific case, to microservices.

</comment></comment><comment><USER14> Microservices are good for large complex systems, with many developers making many changes. It sounds like your system is rather simple, I don't think you need to pursue this architecture, especially just starting out - you'll need to write too much infrastructure and you probably don't need the scalability.

<comment><USER15> Yeah I agree. If prototyping an idea why not start with a monolith and a single DB before going microservices for even scaling is needed?

<comment><AUTHOR> So you would recommend implementing authentication and handling credit cards from scratch? The reason I'm going with this approach is because although I do use a monolith and a single (hosted) DB for my business logic my understanding was that implementing high-impact, high-complexity (non competitive advantage) systems like authentication and credit card handling are best 'outsourced'.

This outsourcing of high-impact, high-complexity does come with the disadvantage of now having to deal with external services. As far as I can tell, the atomicity/transactional problem with these external services generalises to microservices - hence the microservices tag.

<comment><USER15> No of course not.

You have third party thing working like authentication. Bake that into your application in a simple flow where if it works the user gets added to the database or gets access etc to things. Then you would be able to use transactions in the DB

</comment></comment></comment></comment><comment><USER16> This may not be the solution you are seeking, but I would do this with an asynchronous job model. Kick off a job where each stage is a dependency on the previous stage. A failure of any stage will kickoff a cleanup job. The account creation service would be responsible for creating the job and monitoring the status. You could run jobs with whatever you see fit. A kafka consumer would be an interesting option. For a quick POC you could even do it in Jenkins via the API.

</comment><comment><USER17> Calling external services "microservices" is fundamentally wrong. They are "services". All that will do is create a lot of confusion because you are utterly misusing terminology. You can't just decide to misuse terminology. That's like calling "red" "blue". You don't gain information by misusing well- defined terms, you create confusion and misinformation.

That said, your ideas on distributed systems is wrong. Any point in a workflow can and will fail. You need to account for all of this. You can successfully create an account on Stripe, and then when you bill that account, it could return an error. Or even worse, it can timeout, meaning you don't know whether or not a user was charged.

You have to take into consideration all of these failure situations. There is no atomicity in the way that you expect. Whenever things deviate off the happy path, you fail quickly and decisively so that everyone knows where they stand. That gives people the option to retry or call support.

<comment><USER18> What's the practical difference between having an internal microservice which handles subscriptions/charging and using Stripe, for example?

</comment></comment><comment><USER19> Hate to shill, but this is a problem we faced where i work and we wrote a great article about our solution [https://engineering.shopify.com/blogs/engineering/building-r...](https://engineering.shopify.com/blogs/engineering/building- resilient-graphql-apis-using-idempotency)

</comment><comment><USER20> Simplest Thing That Could Possibly Work:

I would look at keeping track of what substeps have completed, and only treat the user as created if they're all done.

You _could_ roll back the successful ones if not everything worked, but you could also just let them be.

</comment><comment><USER21> Google "sagas" - it is a pattern that helps with this, rollbacks across boundaries, etc

</comment><comment><USER22> There are no correct answer that applies to all architectures. But generally speaking you have a core that use the services like black boxes with API's. The core/caller need to handle the errors.

</comment><comment><USER23> 2 phase commit and transaction commit / rollback. Think about boundaries and domains

<comment><USER2> That's not what the OP is asking--they're using external services like Stripe. Creating a Stripe charge isn't something you can roll back.

</comment></comment><comment><USER24> There is no one-size-fits-all approach to atomicity in microservices. Microservices typically want to store the most minimal amount of state possible, and push the coordination up a level; i.e., the calling service will send all the relevant information to the service that is going to handle this tiny piece of the work. Eventually there is going to be one service that owns some sort of workflow, and pushes the rest of the world in the direction of its desired outcome.

A year or so ago I needed to write a service to rotate accounts on network equipment every day or so. The control channel and the network hardware tended to be flaky, so I designed a state machine to make as much progress as possible, and be able to pick up where it left off. Each newly-created account was a row in a transactional database, and the successful completion of the operation was noted by changing a column from NULL to the current time. The flow was; if a new account is needed, generate the credential (generated_at). Find the old credentials and log into the device. Add the new account (applied_at). Try logging in with the new account (verified_at). Wait until account expiration (2 days later). Delete the account (deleted_at). Verify that we can't log in with the old account (delete_verified_at).

From this data, we could see what state every account was in, and query for a list of operations that needed to be performed. (Or if nothing needed to be done, how long to sleep for so that we would re-run the loop at the exact instant when work needed to be done, not that it was critical.)

I believe that your account creation and account deletion should follow a similar workflow. Accounts that fail to be created after retrying for X length of time should just move into the deletion workflow.

The user creation service and the day-to-day user operation service should probably be the same thing. The "user" row in your database should be what the state machine uses to figure out what operations need to be performed.

A user record would probably look something like:

      username, password, email, ... = <stuff your user gives you>
      created_at = <now>
      stripe_account_id = <what the stripe account creation rpc returns>
      stripe_account_verified_at = <time when you verified that the stripe account works>
      auth0_account_id = ...
      auth0_account_verified_at = ...
      delete_requested_at = <when the user clicked "delete account" or you decided you don't want to retry the above steps any more>
      stripe_account_delete_verified_at = <time that you ensured the account is gone>
      auth0_account_delete_verified_at = <ditto>

Now you can do queries to figure out what work needs to be done. "select username from users where delete_requested_at is null and stripe_account_verified_at is null" -> create stripe accounts for those users. "select username from users where delete_requested_at is not null and auth0_account_delete_verified_at is null" -> delete auth0 accounts for those users.

The last bit of complexity is to prevent two copies of your user service from running the query at the exact instant and deciding to create a stripe account twice. I would personally just run one replica of that job. This makes deployments slightly more irritating, since no user creation can occur during a rollout (when the number of replicas is 0), but it sure is simple. I worked on a user-facing feature at Google that did that, and although I hated it, it worked fine. It is also possible to add a column to lock the row; check that stripe_account_creation_started_at is null; change it to the current time; commit. Only one replica will be able to successfully commit that and progress to the next step, but then you need a way of finding deadlocks (the app could crash right after the commit) and breaking them.

It is a little complicated but I personally would rather have exact accounting of what is happening and why, rather than guessing when some user logs in and doesn't have a stripe account.

Edit to add: one last bit... I like running this all in a background loop that wakes up periodically to see what needs to be done, but your createAccount RPC should also be able to immediately wake this loop up. That way if everything goes well, you don't add any latency by introducing this state machine / workflow manager. If something happens like Stripe being down... progress will resume when the loop wakes up again. For that reason, I think you should be explicit and provide the end user with a system that lets them request an account and lets them check the status of the request. (Maybe not the user directly, but your signup UI will be consuming this stuff and providing them with appropriate feedback. You don't want the createAccount RPC to just hang while you're talking to Stripe and Auth0 in the background. Probably. The happy case might take a second, but the worst case could take much longer. Design your UI to be good for the worst case, and it will be good for the happy case too.)

<comment><AUTHOR> I like this approach: it closely matches my initial instincts of having a 'transaction' table for each type of event, with columns for each of the steps. The reason I'm weary of this approach, is because I have done an implementation of this in the past but it turned out to become a nightmare - this is most likely due to a combination of the complexity of that particular domain, my inexperience with this type of problem and external pressures.

I did find some pretty good resources on Sagas - do you have any thought on comparing Sagas pro/cons vis-a-vis this approach?

<comment><USER24> I do not know much about sagas.

I like this approach because you need this user table anyway (probably!) and no data is duplicated in your system. There is one authoritative place that maps username to stripe id, and the logic to work on computing that (making stripe api calls, retrying) lives inside the system that is responsible for telling other parts of your infrastructure that ID. So you do get a consistent view from everywhere; no system will ever have the "wrong answer".

The complexity here comes from handling every possible transition. With an ad- hoc approach, some transitions are hidden and can be ignored until they actually happen. With this approach, you have to think about it all up front and write the necessary unit tests.

The first version of my password changer thing detected states I hadn't thought about and just sent an alert for someone to manually do something. There was a control plane outage and everything broke one day, and that forced me to implement some of the automatic cleanup. Some other comments suggest "don't write this, just send your ops team an email when something breaks" and that is fine for the initial version. All you really want is a detailed record of what's happened and what went wrong, from there you can either fix it one- off, or finally write the code to fix it automatically. You don't need to implement retries and rollbacks on version 0... just flag the account and go fix it yourself until you decide you'd rather have the computer do it.

</comment></comment></comment><comment><USER25> event sourcing and the notion of compensating transactions go along way in solving these types of problems.

<comment><USER26> I did a find for 'event sourcing' in this thread and yours is the single hit at the time of my comment. I came here to agree, and tell the OP that you indeed would benefit from an Event Sourcing Architecture.

<comment><USER25> thx :-) i get the impression event sourcing for the uninitiated is too abstract a concept and is often confused with event-driven architectures.</comment></comment></comment>


Books that helped people through depression - <AUTHOR> http://shelfjoy.com/shelfjoy/bibliotherapy-10-top-picks-to-help-you-deal-with-depression <comment><AUTHOR> Here are just ten. Are there any that you recommend?</comment>


Porsche, Boeing Team Up on Planes in Future Urban Mobility Race - <AUTHOR> https://www.bloomberg.com/news/articles/2019-10-10/porsche-boeing-team-up-on-planes-in-future-urban-mobility-race <comment><AUTHOR> > Commercial flying taxis could take off within the next five years, Boeing > Chief Executive Officer Dennis Muilenburg said last week. Daunting hurdles > remain before drones can be widely deployed, including an air traffic > management system capable of staying on top of a chaotic city environment.

The second sentence of that paragraph does not, to me, appear to match a 5-year time-frame.</comment>


How to transfer tacit knowledge in organization - <AUTHOR> https://twitter.com/iamhuy/status/1118347303532650496 <comment><USER2> _Tacit knowledge (as opposed to formal, codified or explicit knowledge) is the kind of knowledge that is difficult to transfer to another person by means of writing it down or verbalizing it._

[https://en.wikipedia.org/wiki/Tacit_knowledge](https://en.wikipedia.org/wiki/Tacit_knowledge)

<comment><AUTHOR> Thanks for sharing. I understand the definition, but I'd say that by documenting these market interactions down, we're giving our colleagues a better intuition of the market/industry.

Granted it will be some further steps before they actually acquire these tacit knowledge, but it goes a long way into showing them what's it like.</comment></comment>


What Functional Programming Is and Why It Makes You Better - <AUTHOR> http://blog.functionalworks.com/2015/08/04/whatfpisandwhymakesbetter/

<comment><USER2> Is it just me or is the link broken?

<comment><AUTHOR> It works for me. Hmmm. I'll just paste it here: [http://blog.functionalworks.com/2015/08/04/whatfpisandwhymak...](http://blog.functionalworks.com/2015/08/04/whatfpisandwhymakesbetter/)</comment></comment>


Astrid Kirchherr, Who Helped Create the Beatles' Image, Has Died - <AUTHOR> https://www.nytimes.com/2020/05/16/arts/astrid-kirchherr-dead.html <comment><USER2> Backbeat is a pretty good movie about Stuart Sutcliffe and his relationship with Astrid, John Lennon, and pre-fame Beatles. [https://www.imdb.com/title/tt0106339/](https://www.imdb.com/title/tt0106339/)</comment>