Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jan 31 2019 19:32

    prolic on v1.10.3

    (compare)

  • Jan 31 2019 19:32

    prolic on master

    update changelog (compare)

  • Jan 31 2019 19:29
    prolic closed #176
  • Jan 31 2019 19:28
    prolic commented #186
  • Jan 31 2019 19:28
    prolic closed #186
  • Jan 31 2019 19:28

    prolic on master

    fix restarting projection durin… respect lock in memory resetting projection and 12 more (compare)

  • Jan 31 2019 16:26
    fritz-gerneth commented #189
  • Jan 31 2019 16:21
    prolic commented #189
  • Jan 31 2019 16:06
    sandrokeil commented #189
  • Jan 31 2019 15:31
    grzegorzstachniukalm synchronize #186
  • Jan 31 2019 15:23
    kamil-nawrotkiewicz edited #76
  • Jan 31 2019 15:22
    kamil-nawrotkiewicz edited #76
  • Jan 31 2019 15:22
    kamil-nawrotkiewicz opened #76
  • Jan 31 2019 15:19
    grzegorzstachniukalm synchronize #186
  • Jan 31 2019 15:09
    grzegorzstachniukalm synchronize #186
  • Jan 31 2019 13:54
    coveralls commented #186
  • Jan 31 2019 13:48
    mrook commented #189
  • Jan 31 2019 13:41
    prolic commented #189
  • Jan 31 2019 13:40
    prolic commented #189
  • Jan 31 2019 13:31
    fritz-gerneth commented #189
Fritz Gerneth
@fritz-gerneth
I personally don't use generators either. in particular with constructor promotion & readonly creating VO/Events/Commands has become very easy
Alexander Miertsch
@codeliner
@fritz-gerneth well, creating the pure structure might be easy, but how do you handle from/to plain data conversion, validation, public contracts, ...
You can derive all of that from a single sticky note on an event map + it serves as documentation as well
Sandro Keil
@sandrokeil
We are not talking about old code generation :smile: we generate sophisticated code via PHP AST which can be changed by the developer and will not be overwritten. You just implement the business logic and don‘t waste time anymore to implement boring (glue) code. The time saving is amazing. You can also write your own code generator or extend an specific implementation. Cody is your Copilot and does all the monkey work. :smile:
Fritz Gerneth
@fritz-gerneth
consider me a skeptic - a fan of no magic in my code:) (too much bad experience :)) but that really is preference / my 2c :) . One thing I am sure you already have considered is backwards compatibility within the model (i.e. new event properties, removed event properties, not everything needs upcasters, but even upcasters want to be generated :))
Darryl Hein
@darrylhein
my 2¢: the number of times I've changed a major piece of architecture (ie, framework, db, etc) on a whole project is near 0 so the benefit to me of having something decoupled from frameworks is low. Because I maintain dozens of smaller projects, to me having it coupled to a framework or library so I can update it to get the new features is better than trying to update code within the project. If it is possible to have a generator that can update the code with my changes mixed in later, I'd probably be more interested, but the reliability of that concerns me (it'd have to be 99.9% reliable or give a few clear instructions on what to check). There are parts that make sense to have decoupled (like a payment processor or email/message provider), but the number of times I've used a decoupling are so few the extra effort has almost never been worth it. In this case, it seems like I'd be at least partially tied to Cody – not in the same way as a framework, but still reliant on it for future updates. It's always a tough call to find the balance between coupled and decoupled...I don't know that I have ever found the perfect spot.
Alexander Miertsch
@codeliner
@fritz-gerneth that's the reason why I'm asking for feedback. Many developers seem to be skeptic. We're looking for ways to change that ;) "Magic" is a good keyword here. We somehow need to communicate clearly, that Cody is not magic. I'm still not sure about the best way to do that.
Let's try it like this:
Usually developers are lazy. They try to automate repeating tasks and make their life easier. That's the key idea behind Cody as well.
Once you've found rules and conventions how to organize your code base, you'll do the same coding over and over again:
Create this class here, configure message routing there, set up an API endpoint, map data to VOs, define a contract (e.g. OpenAPI/AsyncAPI files) and so on. Isn't that boring?
Why not automate the boring parts? Writing the automation logic is a purely technical and depending on how crazy you want it to be also a challenging task. Something developers usually like. If you write and maintain the logic yourself would you still say it's magic?
Alexander Miertsch
@codeliner

@darrylhein good point. The context is super important. For companies with multiple teams all working with the same basic set up and maintaining software over a long period of time, framework decoupling is much more important than for smaller single team projects. A framework often influence the way how problems are solved in code. what works good today, can become a huge problem tomorrow when you want to scale (technically and in teams size)
Another good reason for decoupling is much cleaner business logic that is easier to understand and change over time.
But a framework agnostic domain model means:
more glue code required to make it work with your current framework of choice. But if you automate glue code generation as well as parts of the domain model code itself then you have a win-win situation.

if it is possible to have a generator that can update the code with my changes mixed in later, I'd probably be more interested

that's actually the case. It works like rector or a code sniffer. In rector you have those rules to upgrade parts of the code to a new PHP version. It also modifies your code without destroying it. Cody can do the same. If a VO exists already, Cody does not touch it! But if you want to add a new interface and/or method to all VOs, Cody can easily do that while keeping the original implementation in place.

Fritz Gerneth
@fritz-gerneth

we are maintaining a single low-time project (ever since starting to use prooph :)), so no need to upgrade multiple things, just making sure things keep on running / evolve with least effort :) ( Also, no hostility meant, I am being honest but not judging, there absolutely is a value of what you suggest)

when I talk about magic, I mean magic in code. I like stupid code. I like obvious code. I spent way too much time of my life debugging / figuring out why something magically does not work (any kind of magic routing / loading / ... ). I prefer repetitive over magic.

When we (team) implement new features, the basic setup is the stuff that takes the least time. Setting up read models / projections is what takes the most time (although repetitive but way more time consuming). That's the place where I personally would like to cut effort (esp since we use json functions and these are a PITA).

Darryl Hein
@darrylhein
@codeliner My experiences with Rector and other CS tools has been mixed. Most of the time it's perfect, but I recently had a Rector change break production as it wasn't terribly obvious what it did. I think Rector/similar and frameworks have the same issues in that area – both can result in invisible changes.
Darryl Hein
@darrylhein
I think for almost all teams it's deciding where to couple and where to decouple. A 100% decoupled system would be the most ideal, but there's no way that's going to reality – eventually you have to run on a computer, probably with a BIOS....unless you really want to go that deep. So then it's just how far or which parts do you couple to.
Alexander Miertsch
@codeliner
@darrylhein I don't know how critical that bug was, but compare the time saved by rector versus that one bug and compare it also with that imaginary number of bugs caused by humans doing such a refactoring.
The good thing about automation is: if it works once, it'll always work for that case. You save time and reduce the risk of silly mistakes made by developers who are bored to do the tasks.
Most bugs I produce are the result of boring work. When I'm 100% focused on the task, my code usually works. With or without tests ...
If I have to map data back and forth, write validation logic by hand etc. it happens more often that a bug slows me down. A spelling mistake for example. Of course most of the time I fix the bug even before committing the code, but it's still a waste of time. You know like wondering for an hour why the hell it's not working just to find out that you did a spelling mistake in a mapping ...
Darryl Hein
@darrylhein
@codeliner Well, users weren't able to create the primary item in the system. Of course that system doesn't have great testing, so that didn't help.
But, yes automation is great – use it all the time. I'm the Rector, CS, etc train.
But, I don't think automation > framework coupling.
There are apparently thousands of companies coupled to, all sorts of things. I don't know that if the team gets larger they're less likely to be coupled. From my experiences (in multi-billion $ companies), they were using an awful lot of coupling. It made it easier for them to hire.
But, in the end, it's a just a choice to decide at what level you uncouple at. If Prooph goes that (code gen) way, I'll have to see how it works and go from there.
Silviu
@silviuvoicu
Let's asume that the product/project is quit complex, and for us to resolve we need first some design before we code something. Here, we have multiple choice and formats, either on wall(oh, well, after pandemic) or in platform like prooph-board. And after the design, we should go to the implementation. Now, probably we have to made some choice about what we will use: use a particular framework for help us with the implementation, maybe use some code auto-generated, what kind of event store to use for the app or what database will be appropiate for the read models, among other things. With a framework, will have a way to write our aggregates, events, projections and maybe, maybe some tests without caring some much of the infrastracture cause the framework had made that choice for me, and if I don't have a special requirements to add something new functionality, then I am fine. With the code-generated, I willl generate the structure of some pieces like aggregates,events and so on and probably let me write the infrastructure code that will glue all things together. If will code -generated also some test from my model space, even better, maybe in form of given/when/then format style, but usally that's somehow couple of infrastructure code, which is either provided as it is by a framework or is custom made. I think, that whatever we choose to go on this road, it has to be focus on the problem we have to solve, to provide the tools either by a framwork or by code-gen tool, but also to provide some sort of flexibility, be able to do some sort of customization when need. But, to test yours idea, maybe not just some opinionated suggestion are what you need, but also an mvp, working example, you know, go to your customer and ask/communicate with them :), either company or developers.
Alexander Miertsch
@codeliner

@silviuvoicu

maybe not just some opinionated suggestion are what you need, but also an mvp, working example, you know, go to your customer and ask/communicate with them :), either company or developers.

yeah, that's the point.
We're in direct exchange with our customers and we demonstrated one real world result of what is possible with prooph board + Cody in a live demo session at EventSourcing.Live last year. BTW the recording is now available on youtube: https://www.youtube.com/watch?v=lKB8-l9MEvs
There you can see the potential incl. fully working FE and BE code generation.

We could release the Cody implementation used in the live demo as an example. But my fear is that people would think it's the only way to work with Cody:
Cody itself is an API. It gives you access to your design on prooph board. Now it is up to you, what you want to do with that information. Generate some boilerplate code, scenario tests or a fully working low-code platform.
Is this too low-level for developers? Because it requires too much learning effort?

I'd love to share the excitement with you. But I try to figure out what would be the best way to do that.

Fritz Gerneth
@fritz-gerneth
@codeliner some interesting things in the video for sure :) some follow up questions:
  • how do you handle validation (as it's skipped in the video)?
  • how do you handle logic (be it validation, read model logic, aggregate logic) that you cannot define in json (i.e. we have complex internal aggregate states etc..)? obviously I can add it in the generated code later on, but how would later updates on the board (and code re-generation) affect my custom added code?
  • how does the board handle "branches", think of different features worked on in parallel? how would branches be merged on the board level?
  • as we have to maintain our software for years (current installment for ~10 years), we have seen a lot of these tools come and go ;) not being maintained is one thing as long as they remain in our build chain, but SaaS really breaks away forcing you to look into alternatives.. I know the code generated is on our git, but it still breaks established workflows. any plans to bring the board as a self-hosted / run version? ideally as something I can define as a dependency on the project and start like "any other code generator" (just with a graphical UI instead of CLI).. running locally also would be preferred from a security & confidentiality perspective
Alexander Miertsch
@codeliner
@fritz-gerneth
Before I answer your questions I'd like to stress the point that the answers related to code generation are specific for the set up shown in the video. That said, you can build your own code generation logic the way you want/need it. @sandrokeil Put a lot of effort into an abstraction layer on top of PHP Parser to simplify code generation. It's organized in libs for specific tasks. Check out the github orga Open Code Modeling
Alexander Miertsch
@codeliner

Validation:
We translate metadata on prooph board to JSON Schema. I've skipped validation in the video to save some time but here are two examples from the same app:

{
  "shorthand": true,
  "ns": "/Common",
  "voNamespace": "/Common",
  "schema": {
    "userId": "string",
    "givenName": "string",
    "familyName": "string",
    "roles": "/Common/Roles",
    "email": "string|format:email"
  }
}

It's metadata for a UserInfo VO. As you can see the shorthand version of json schema is used (our own creation, we have a translator to real json schema) and we can type hint properties with definitions (other VOs in the code) and define json schema validation like "email": "string|format:email"

Another example of a specific link validation. Here we had to define normal json schema (note: shorthand: false), to be able to define a regex pattern for validation.
{
  "shorthand": false,  
  "ns": "/Expose",
  "voNamespace": "/Expose",
  "schema": {
    "type": "string",
    "pattern": "^((eigentumswohnung(en)?-)|(condominiums-))[üäöÜÄÖßA-Za-z0-9-]+$"
  }
}
Alexander Miertsch
@codeliner
With this information we do two things:
  • Generate fully typed, immutable VO structures with self-contained data mapping capabilities (from/to native data) respecting the defined namespaces (ns, voNamespace) in the schema
  • Generate JSON Schema based API contracts that are also used for input validation on API level
Alexander Miertsch
@codeliner

how do you handle logic?

As mentioned by @sandrokeil the code generation layer is designed in a way that it can modify existing code without breaking it. Thanks to PHP Parser AST. That said, the goal is not to define everything on prooph board. You design the flow of information, document structures and responsibilities. But business logic insight aggregates or read model logic insight projections is still done by the developer. Cody supports developers with boring tasks. It's a code monkey :) You should really try it! It's so nice to have all the boilerplate in place and just focus on the challenging parts like complex aggregate logic. Messages, VOs, API all ready to use. And the documentation is already in place! And can be used as a starting point for the next design iteration! All the litte things add up quickly to huge time saver. It's not only the one hour saved, by not writing boilerplate code by hand.
The feature in the video works out-of-the box because the Cody implementation used is designed for Event Engine and it generates some common defaults that make it possible to have the whole thing working without touching the code itself. But others features of that app also have hand written parts in use.

Fritz Gerneth
@fritz-gerneth
@codeliner thanks :) that pretty much what I was thinking as well, hope I get the time to give it a try the next weeks.
on a related note, https://event-engine.io/ does not resolve for me
3 replies
Alexander Miertsch
@codeliner
An example: let's say you have an aggregate with some existing methods and implemented business logic. Now on prooph board you design a new feature and this existing aggregate should handle a new command. Your existing aggregate class will be parsed into an AST. The code generator will check if a command handling method exists in the AST and if not, add it. The rest of the ast remains untouched.
image.png

how does the board handle "branches"

above you see a feature tagged as "planned". It appears yellow on the board. That's how we design new features in an existing system. We also mark changed information or messages with hot spots and write down what will change.

Alexander Miertsch
@codeliner
As shown in the video, you as a developer select the elements on prooph board that Cody should handle. So if you want to generate a new feature into a feature branch of your git:
  • checkout a feature branch
  • select the new feature on prooph board
  • trigger cody
Alexander Miertsch
@codeliner

I know the code generated is on our git, but it still breaks established workflows. any plans to bring the board as a self-hosted / run version?

Two things:

  • we have this case already with allmyhomes. If prooph board would be taken down tomorrow they would run into a problem, because their dev workflow is somewhat depending on prooph board. I mean you can work with out of course, but it would slow down everything for a while (well, back to the situation before prooph board ;))
    So we're currently designing a contract that protects our customers from that risk. It includes an option to buy a copy of the tool in case we stop the service for whatever reason.

And yes, we also offer self-hosted options. But they are more expensive.

ideally as something I can define as a dependency on the project and start like "any other code generator" (just with a graphical UI instead of CLI).. running locally also would be preferred from a security & confidentiality perspective

@fritz-gerneth That exists! Cody is open source and can be installed via composer. The free version of prooph board is hosted on github and requires no login at all! Everything that you do there happens only on your local machine within your browser. You can import/export boards etc. But without the SaaS version you cannot collaborate with your teammates (yet). We're working on making that possible in the free version as well. That should become available at some point in this quarter, but will have limitations. We still want to earn some money with the SaaS version :D
The free client is available here: https://free.prooph-board.com

Alexander Miertsch
@codeliner

@fritz-gerneth if you really want to try Cody, let me where you need support. A good starting point is the tutorial:
https://wiki.prooph-board.com/cody/php-cody-tutorial.html

It covers the absolute basics. @sandrokeil could support you in exploring the "Open Code Modeling" stuff and we could open source the Event Engine implementation shown in the video if that is of interest as well. But this is highly opinionated :D

Fritz Gerneth
@fritz-gerneth
yep, will give it a try
Alexander Miertsch
@codeliner
cool, looking forward to your feedback!
Fritz Gerneth
@fritz-gerneth
( in particular if it helps with the API integration, that is something far more tedious than the actual model imho :))
Alexander Miertsch
@codeliner
absolutely! Currently, I'm working on a new feature in prooph board that you can mark events etc. as public contracts with a version. Those public contracts can then be linked on other boards (each team has its own board). From this linking architects can derive a high level dependency view (upstream, downstream deps) and later the consuming team will be notified if the contract will change.
Fritz Gerneth
@fritz-gerneth
sounds interesting :)
Alexander Miertsch
@codeliner
customer wish ;) And a good reason to work with us. Our goal is to make the development of event-driven systems as easy as possible. Therefor, we work together with our customers and try to eliminate all hot spots. Dependency management across teams is definitely one of the major problems in larger corporations.
Fritz Gerneth
@fritz-gerneth
not so much larger team, 6 devs, but rather agile / fast moving / changing :)
hence all that focus on BC / ... :)
Alexander Miertsch
@codeliner
we also try to fix the problems for smaller teams ;)
Sascha-Oliver Prolic
@prolic

just released: https://github.com/prooph/event-store/releases/tag/v7.7.0

special thanks for @gquemener and also thank you @netiul for reminding me to take care of this.

spread the word!

Zacharias
@netiul
:D you're welcome
thank you
Silviu
@silviuvoicu
Hope that event-store- client will follow :)
Dariusz Gafka
@dgafka
Hey @prolic @codeliner
Are there plans for supporting event-store-client library and providing PHP8 support?
Sascha-Oliver Prolic
@prolic
Yes, if you have time to submit a PR, do so. Otherwise you'll have to wait until I get to it
Sascha-Oliver Prolic
@prolic
I took 1-2 hours today and started refactoring event-store-client. In case you use it in production, pin your composer.json to the current commit in master. Otherwise things might break once I'm done and it gets merged to master.
I'm switching back and forth between Haskell and PHP development at the moment, so don't expect me to be ready too fast.
Sascha-Oliver Prolic
@prolic
I added a few hours more, deleted already ~3000 LOC
Sascha-Oliver Prolic
@prolic
almost done:
FAILURES!
Tests: 182, Assertions: 165, Failures: 1, Risky: 74.
that's with --stop-on-failure
in total there are ~300 more tests
Sascha-Oliver Prolic
@prolic
around 50% of the tests already pass