Gregor Hohpe is the author of Enterprise Integration Patterns and writes on messaging, system coupling, cloud architecture and scaling organizations.
HN recommends the Enterprise Integration Patterns book and site for messaging and queues, and likes the Starbucks article on why coffee shops skip two-phase commit.
>> i can't tell the difference
> i did see differences.
Spot the difference. ;-)
> but i can do the same in pike if i tried, and i expect in lisp and other languages too.
Absolutely you can! You can even do it in C: write yourself a message-passing library in C. You might want to call it Objective-C. Or do a VM for Smalltalk.
> where then is the great revelation that comes from smalltalk?
The claim was not that the great revelation came from Smalltalk, but that it came from message passing:
>>> Message passing belongs up there with lisp, forth and pure functional programming as paradigms that are worth learning for "the profound enlightenment experience you will have when you finally get it."
Smalltalk isn't even mentioned in that little section about the enlightenment.
And in fact, Smalltalk's form of message-passing is pretty limited, it only just extends beyond method invocation and it certainly can be (and is) frequently used just like method invocation. If you want to do more sophisticated things, you mostly have to go via the DNU handler, which is a bit hacky.
And in fact, Alan Kay's famous OOPSLA '97 quip "I made up the term object oriented. And I can tell you I did not have C++ in mind." was followed immediately with the slightly less famous "So, the important thing here is: I have many of the same feelings about Smalltalk". https://www.youtube.com/watch?t=634&v=oKg1hTOQXoY&feature=youtu.be
And even message-passing is much broader: for example,…
They make a couple products that work well together. Mule ESB acts as a container for flows, which are declaratively-written processes of canned components that do a specific thing (like make an SQL query, make API calls, or call your custom code), or EIP components [1] that manipulate the execution flow. They give you a visual editor to drag-and-drop build these flows, or you can write them by hand in XML. You deploy them in Mule ESB and they run indefinitely, accepting messages, say, on HTTP ports, or firing at set times like cron-jobs, or the like; the runtime detects most crashes and restarts the particular flow if something goes weird. If this kinda sounds like Erlang/OTP you're not entirely wrong, but, let's not go there...
(okay, so the canned components are sometimes quite nice, whereas in vanilla Erlang you're on your own. The value something like Mule brings is more the abstractions and the ecosystem, even if the Java runtime is of no intrinsic help. Also, see RabbitMQ's slides on Erlang [2]. Mule isn't an outward-facing message middleware like RabbitMQ, but behaves a lot like one on the inside. It also gives canned components to interact with them.)
A Mule flow is often basically mid-level business logic plumbing; you don't want to put these flows on the public internet without rate limiting, authentication and authorization -- you want to use some API gateway or proxy in front. Mule has one, called Mule API Gateway, and the front-facing portal API Manager. Then…
Your comment seems to be a slightly clumsy way of saying "I don't know much about this area of software design, please tell me more", so I'll respond to it in that spirit.
Firstly my terse hand wavey statement was at least clear on the fact that it was talking about communication between services. It said nothing about web browsers or any other human interface.
But since this relatively narrow context is clearly the one which you can most relate to, I'll stay within it. If you think about it, the HTTP request/response cycle is actually an illusion of synchronous communication on top of a transport mechanism which is fundamentally asynchronous. It's an abstraction layer which shields you from the complexities of asynchronous communication. Broadly speaking this is known as the [request/response](https://en.wikipedia.org/wiki/Request%E2%80%93response) pattern.
HTTP by no means the only implementation of the request/response pattern. Even in asychronous messaging systems it's not unusual to see it implemented - https://www.enterpriseintegrationpatterns.com/patterns/messaging/RequestReply.html.
But request/reply is just one of the patterns which exists in the realm of asynchronous communication. There are other, much more common patterns such as send/receive and publish/subscribe. Exploring these patterns opens up whole new approaches to software design.
I wholeheartedly recommend the book [Enterprise Integration Patterns](https://www.enterpriseintegrationpatterns.com/) by…
It is a pity that so much effort has been put on writing/designing this booklet. Software Architecture is very hard to 'compress' into a booklet this size. And the concepts explained seem all mixed up. Also, I never understood the difference between Software Architect and Solution Architect, I think they are just marketing tags to specify a bit more what you can do as an architect (install/customize a turn-key solution, networking architecture, software development guidance from scratch, etc).
There is so much noise in the space of Software Architecture. And I think is something natural: building software is not architecture, nor engineering, nor mathematics... still it is all that at the same time. It also has strong social, linguistic and design components. Maybe it is just too new a discipline to define it clearly.
Personally I find these resources more convincing than the booklet or the references mentioned inside it:
For the technical/organizational (Dev teams) part
Architecture without Architects: https://www.youtube.com/watch?v=qVyt3qQ_7TA
Clean Architecture: https://www.youtube.com/watch?v=Nsjsiz2A9mg
https://www.amazon.com/Things-Architect-Knows-About-Transformation/dp/1537082981/ref=sr_1_1?s=books&ie=UTF8&qid=1545832595&sr=1-1&keywords=37+things+architect+knows
https://www.enterpriseintegrationpatterns.com
For the Enterprise Architect…
Perhaps due to the title (which is evocative in Seattle) I often think of "Starbucks Does Not Use Two-Phase Commit" [0]
[0] http://www.enterpriseintegrationpatterns.com/ramblings/18_starbucks.html
P.S.: I feel like I may have thrown this one out without enough context, so I'm just gonna bloviate a bit in this edit.
The "object" referred to in the OP link -- or what I like to vaguely call the "unit of consistency" -- is a single Starbucks employee. They hopefully have an internally-consistent history of what they believe to be true about the universe. (And stay sane during coffee-rush times.)
The phrase "eventual consistency" describes the relationship between multiple employees. Individuals can drastically disagree with one-another, but there's a framework for detecting disagreements and resolving the discrepancy in some way, even if that just means agreeing to ignore it and logging it for management to fix.
A lot of eventually-consistent systems involve allowing certain kinds of discrepancies to occur, while simultaneously promoting those errors into real business concepts in the domain. Banking and accounting systems are particularly great demonstrations of this, because they started doing it centuries ago when nodes were in cities connected by ink-and-parchments packets on horse-ridden routes.
The workflow/orchestrator pattern is key to keeping services decoupled and simplifying your code. I'm working on a Typescript library to encapsulate all the technical detail in https://github.com/node-ts/bus/tree/master/packages/bus-workflow so that you only worry about message inputs and outputs keeping it easy to see the logical flows of your system.
It's Inspired from the EIP pattern (https://www.enterpriseintegrationpatterns.com/patterns/messaging/ProcessManager.html) and frameworks from other languages that have had this type of thing for years.
The author also hints about an alternative, commonly known as "routing slips" (https://www.enterpriseintegrationpatterns.com/patterns/messaging/RoutingTable.html), where the "next step" is loaded into the message header and gets passed down to the next handler as part of a broader process. This removes the need for a centralised orchestrator, but has a huge downside of being tough to handle failure paths, compensating logic or switching logic.