Saying this is reinventing BASIC in YAML seems to miss the point here; the programming model here is essentially a finite state machine with optional data flowing between nodes, and AFAIK there isn't really a widespread language that targets this model.
And a restricted model is not there just so that non-programmers can use it. Restricting what you can do in the program means that there are more things you can do with the program. I haven't checked if GCP's Workflows supports everything below, but here are some things you can do in principle:
* You can visualize the entire program as a flowchart, and visualize the state of the program simply by pointing at a node in the flowchart. This is not possible with a general purpose language since there could be arbitrary levels of call frames.
* You can implement retry policies for each step entirely transparently, and possibly other things like authentication. Aspect-oriented programming is more practical when the programming model is restricted.
* You can schedule the steps onto different hosts, possibly in parallel.
* You can suspend and resume the workflow, since its entire state is just which step is being executed, plus a handful of variables (which presumably are always serializable).
Re the problem of extension: the idea seems to be that you put all "smartness" inside HTTP services that are written in real languages and only use this as a dumb glue language.
Look at my project temporal.io. It does the same thing using general purpose programming languages. Currently Java and Go are supported with Python, Ruby and C# under development. This is absolutely valid workflow code:
That is good, but why code all that up in YAML? This looks to me like a programming language with great efforts made to obfuscate the fact.
We've had 70 years to figure out what good programming language layout looks like. I think there is almost a consensus that it doesn't look like the linked code-wearing-a-fake-moustache .
Are people supposed to code these state machines using some sort of real language then translate it to YAML?
Data is data. Code is logic. So the the thought process goes...
...what if I could store my configuration (data! right?!) in a way that is nicely separated from the logic?! No more scripting for me!
Oh wait. Some of the configuration can't be generalized about universally. Configurations fundamentally contain logic, I guess.
Oh, well then why don't I just represent the logic in the data?! That will be much better than representing the data in the logic!
....but now, you are back where you started, only instead of using something nice, standard, and powerful like Python, you have to use this... language... thing. This YAML convention you cooked up.
Separate the data from logic. Read the data into the logic. Make a nice organized place to call custom logic from... like, you know, a file directory full of scripts, which are called according to some scheme. It could be another data file. Stop there.
Like this:
$ ls -Ra
./config/do_something.yaml
./config/do_something_else.yaml
./config/config.yaml
./logs/ping.log
./scripts/do_something.py
./scripts/do_something_else.py
$ cat ./scripts/do_something.py
from stupid.library.task import Task, subscribe
class DoSomething(Task):
@subscribe
def ping(self, target):
return super().ping(target)
Then you code the program that runs collects all of the task methods, put them in an ordered list, and run them if the conditions in the config.yaml is met.
Every other thing is done in a task method in python, or something like it. I don't think we need more abstraction than that.
The whole idea being that you don't want the story to be turing complete (there are no loops or conditionals with a story), but the code that executes it needs to be turing complete.
I get the appeal of something like this. It's locked down enough that it's perhaps challenging to do something really unsafe with it. It's maybe usable by someone who doesn't feel comfortable with a "real" programming language.
But it seems like this falls apart as soon as one service you need to interact with creates a requirement not anticipated by this very constrained tool-set. You need to query service A, extract something with a regex, base64 encode something else before you post to service B? Well we didn't include regexes, a module/import system, or the ability to introduce UDFs in a different language.
And if you had the resources to make all your services play into the expectations of this workflow system, you might not need to use this workflow system.
I don't see how writing a kinda abstract syntax tree with the opacity of Enterprise JavaBeans is easier than say writing the workflow in some Basic dialect with only GOTOs and IFs.
We went through great lengths to be able to do parameterized YAML using jinja2 templates. I designed a system that let us effectively create a new yaml out of two other yamls which let us handle repetitive configuration tasks reasonably well but there were occasional unexpected challenges thanks to the syntactically significant white space of yaml.
Obviously it's laborious insert to YAML keys everywhere, so I'm developing an editor that integrates YAML and plain text document formats (such as Markdown):
I like this. Go "har har har yaml" all you like, but this reads a damn lot better than AWS step functions and seems way more powerful.
There are a number of tasks that benefit from something like this, and there are a huge number of advantages from being able to encode steps in domain specific languages such as YAML and have them execute with truly "no code".
yaml is not a language. it's a serialization format.
this thing here is a language that serializes into yaml. there are zero benefits of using it except perhaps 'it is yaml so i don't have to compile my configuration'.
note that xml with xslt would have handle it better.
Do they have a graphical tool for defining these workflows? For me this looks like the business process management tools from the past. With those the idea was not to use them to write program logic, but connect the dots on very high level. See for example the use case pictures at [1].
YAML has really good typing support with type annotations being a first class citizen. But you’re dependent on the hosting software (adding or understanding) the types.
[+] [-] xiaq|5 years ago|reply
And a restricted model is not there just so that non-programmers can use it. Restricting what you can do in the program means that there are more things you can do with the program. I haven't checked if GCP's Workflows supports everything below, but here are some things you can do in principle:
* You can visualize the entire program as a flowchart, and visualize the state of the program simply by pointing at a node in the flowchart. This is not possible with a general purpose language since there could be arbitrary levels of call frames.
* You can implement retry policies for each step entirely transparently, and possibly other things like authentication. Aspect-oriented programming is more practical when the programming model is restricted.
* You can schedule the steps onto different hosts, possibly in parallel.
* You can suspend and resume the workflow, since its entire state is just which step is being executed, plus a handful of variables (which presumably are always serializable).
Re the problem of extension: the idea seems to be that you put all "smartness" inside HTTP services that are written in real languages and only use this as a dumb glue language.
[+] [-] mfateev|5 years ago|reply
[+] [-] roenxi|5 years ago|reply
We've had 70 years to figure out what good programming language layout looks like. I think there is almost a consensus that it doesn't look like the linked code-wearing-a-fake-moustache .
Are people supposed to code these state machines using some sort of real language then translate it to YAML?
[+] [-] lowercase1|5 years ago|reply
[+] [-] indymike|5 years ago|reply
[+] [-] xiaq|5 years ago|reply
[+] [-] bonestormii_|5 years ago|reply
...what if I could store my configuration (data! right?!) in a way that is nicely separated from the logic?! No more scripting for me!
Oh wait. Some of the configuration can't be generalized about universally. Configurations fundamentally contain logic, I guess.
Oh, well then why don't I just represent the logic in the data?! That will be much better than representing the data in the logic!
....but now, you are back where you started, only instead of using something nice, standard, and powerful like Python, you have to use this... language... thing. This YAML convention you cooked up.
Separate the data from logic. Read the data into the logic. Make a nice organized place to call custom logic from... like, you know, a file directory full of scripts, which are called according to some scheme. It could be another data file. Stop there.
Like this:
--- --- --- --- Then you code the program that runs collects all of the task methods, put them in an ordered list, and run them if the conditions in the config.yaml is met.Every other thing is done in a task method in python, or something like it. I don't think we need more abstraction than that.
[+] [-] pydry|5 years ago|reply
The whole idea being that you don't want the story to be turing complete (there are no loops or conditionals with a story), but the code that executes it needs to be turing complete.
[+] [-] abeppu|5 years ago|reply
But it seems like this falls apart as soon as one service you need to interact with creates a requirement not anticipated by this very constrained tool-set. You need to query service A, extract something with a regex, base64 encode something else before you post to service B? Well we didn't include regexes, a module/import system, or the ability to introduce UDFs in a different language.
And if you had the resources to make all your services play into the expectations of this workflow system, you might not need to use this workflow system.
[+] [-] rightbyte|5 years ago|reply
[+] [-] perfunctory|5 years ago|reply
[+] [-] baq|5 years ago|reply
[+] [-] 1337shadow|5 years ago|reply
[+] [-] qppo|5 years ago|reply
[+] [-] unknown|5 years ago|reply
[deleted]
[+] [-] recuter|5 years ago|reply
[+] [-] tuankiet65|5 years ago|reply
[+] [-] oblio|5 years ago|reply
[+] [-] dhosek|5 years ago|reply
[+] [-] unknown|5 years ago|reply
[deleted]
[+] [-] osmarks|5 years ago|reply
[+] [-] baq|5 years ago|reply
[+] [-] amyjess|5 years ago|reply
This is basically Lisp without the parentheses.
[+] [-] swiley|5 years ago|reply
[+] [-] thangalin|5 years ago|reply
https://bitbucket.org/djarvis/yamlp/
Along with Pandoc, it allows common prose from Markdown to be de-duplicated, as described in my Typesetting Markdown series:
https://dave.autonoma.ca/blog/2019/07/06/typesetting-markdow...
Obviously it's laborious insert to YAML keys everywhere, so I'm developing an editor that integrates YAML and plain text document formats (such as Markdown):
https://www.youtube.com/watch?v=u_dFd6UhdV8
[+] [-] jpxw|5 years ago|reply
[+] [-] orf|5 years ago|reply
There are a number of tasks that benefit from something like this, and there are a huge number of advantages from being able to encode steps in domain specific languages such as YAML and have them execute with truly "no code".
[+] [-] osmarks|5 years ago|reply
[+] [-] baq|5 years ago|reply
this thing here is a language that serializes into yaml. there are zero benefits of using it except perhaps 'it is yaml so i don't have to compile my configuration'.
note that xml with xslt would have handle it better.
[+] [-] jpalomaki|5 years ago|reply
[1] https://cloud.google.com/workflows
[+] [-] cordite|5 years ago|reply
[+] [-] dpc_pw|5 years ago|reply
[+] [-] throwaway4889|5 years ago|reply
[+] [-] fmakunbound|5 years ago|reply
[+] [-] wickedOne|5 years ago|reply
for a straightforward collection of strings: probably good enough, for anything else xml is more likely to cover the usecase better
[+] [-] Spivak|5 years ago|reply
For example
could actually map to a native date object.[+] [-] unknown|5 years ago|reply
[deleted]
[+] [-] taylorlapeyre|5 years ago|reply