Is there a way to make a herald rule only trigger based on an action not on a state? - phabricator

I am trying to make a herald rule that triggers when someone removes a tag from a task. The way that I came up with was to have a herald rule that asserts that the task has the other traits that I want, then have another herald rule that uses the first herald rule as a condition, then check that the tag is missing as the other condition. So I have
Herald Rule A - Checks that a task has other traits I want to the issue to still have
Herald Rule B - Checks that Rule A is true, but also that the tag I want removed is missing.
So this only protects me from the case where someone makes a new task that both matches the conditions of A and B. This is because the task hasn’t been made yet, so it never matches A (even though the task will match A after it has been made. I should say the conditions of A are themselves set by a third different herald rule and that's why that is true), so in that case, it doesn’t match B and doesn’t do the action in B.
And I thought I was so clever. But then if you made a task that matched A, but also already matched B, it would pass B anytime you make ANY change to that task, not just if you had removed the tag so that it would start matching B. I don’t want that.
I only want my herald rule to pass when it matches A and ONLY when the tag is removed so that it wasn’t matching B before and then starts matching B. If Herald operated on actions and not just states, this would be a lot easier. How can I describe the state to include the state of both before and after whatever action happens that triggers the herald rule?

When creating a global maniphest task herald rule, you should be able to select that the actions are performed only if the rule did not match the last time it was evaluated. This should allow you to have the rule not match if the project has the tag, and then match later on once the project is removed.

Related

DDD and uniqueness constraint

How would one validate a unique constraint using DDD? Let's say that an Entity has a property name that must be unique among the system and there is a specific EntityRepository method nameExists(name): bool... This is what I found people suggests to do, because the repository is the abstraction of the collection of all the Entityies and should be able to perform this check.
So before creating/adding the new Entity the command / domain service could check for the existence of a newName against the repository, but I think that this will not always work because of concurrency.
In a concurrent scenario where two transactions are started simultaneously, the EntityRepository's nameExists method might return false for both transactions, and as a result of this two entries with the same name will be incorrectly inserted.
I am sure that I am missing something basic, but the answers I found all point to the repository exists method - TBH others say that a UNIQUE constraint should be put on the DB to catch the concurrency case, but what if one uses Event Sourcing or a persistence layer that does not have unique constraints?
| Follow up question |
What if the uniqueness constraint is to be applied in different levels of a hierarchy?
A Container's name must be unique in the system and then Child names must be unique inside a Container.
Let's say that a transactional DB takes care of the uniqueness at the lowest possible level, what about the domain?
Should I still express the uniqueness logic at the domain level, e.g. with a Domain Service for the system-level uniqueness and embedding Child entities inside the Container entity and having a business rule (and therefore making Container the aggregate root)?
Or should I not bother with "replicating" the uniqueness in the domain and (given there are no other rules to apply between the two) split Container and Child? Will the domain lack expressiveness then?
I am sure that I am missing something basic
Not something basic.
The term we normally use for enforcing a constraint, like uniqueness, across a set of entities is set validation. Greg Young calls your attention to a specific question:
What is the business impact of having a failure
Most set constraints fall into one of two categories
constraints that need to be true when the system reaches steady state, but may not hold while work is in progress. In business processes, these are often handled by detecting conflicts in the stored data, and then invoking various mitigation processes to resolve the conflict.
constraints that need to be true always.
The first category includes things like double booking a seat on an airplane; it's not necessarily a problem unless both people show up, and even then you can handle it by bumping someone to another seat, or another flight.
In these cases, you make a best effort - you look at a recent copy of the set, make sure there are no conflicts there, then hope for the best (accepting that some percentage of the time, you'll have missed a change).
See Memories, Guesses and Apologies (Pat Helland, 2007).
Second category is the hard one; to ensure the invariant holds you have to lock the entire set to ensure that races don't allow two different writers to insert conflicting information.
Relational databases tend to be really good at set validation - putting the entire set into a single database is going to be the right answer (note the assumption that the set is small enough to fit into a single database -- trying to lock two databases at the same time is hard).
Another possibility is to ensure that only one writer can update the set at any given time -- you don't have to worry about a losing a race when you are the only one running in it.
Sometimes you can lock a smaller set -- imagine, for example, having a collection of locks with numbers, and the hash code for the name tells you which lock you have to grab.
This simplest version of this is when you can use the name as the aggregate identifier itself.
if one uses Event Sourcing or a persistence layer that does not have unique constraints?
Sometimes, you introduce a persistent store dedicated to the set, just to ensure that you can maintain the invariant. See "microservices".
But if you can't change the database, and you can't use a database with the locking guarantees that you need, and the business absolutely has to have the set valid at all times... then you single thread that part of the work.
Everybody that wants to change a name puts a request into a queue, and the one thread responsible for managing the invariant certifies each and every change.
There's no magic; just hard work and trade offs.

Is the order of the list returned by getifaddrs(3) important?

From the getifaddrs(3) man page:
The getifaddrs() function creates a linked list of structures describing the network interfaces of the local system [...]
Does the order of this linked list imply a priority, and if so, what does this priority mean?
No, absolutely not. Routing is completely separate from that list. I'm not sure there's any document that asserts the negative "this is not priority order" (also it doesn't assert that it's sorted by anything else), but in my work using that list it definitely isn't in any priority order. It's just a list.
More importantly, if the documentation doesn't promise an order, then implementations are free to put it in any order they want (and free to change between releases), so you couldn't rely on it even if it were in some useful order on one platform.

Corda: Creating contracts dynamically

In our use case, we need to define certain rules at run-time based on which a node will transact with other nodes in the network. For example, we want to define a rate at the front end and check that the transaction is happening with this rate only for that particular node. In other words, can we define the terms and conditions at run-time and would this still be called a smart contract or does a smart contract need to be always hard-coded. Is there any alternate way to look at this?
The contract itself is hard-coded. This is because every node needs to agree that a given transaction is valid according to the contract rules, forever. If they varied based on the node, some nodes would consider a transaction valid while another would consider the transaction invalid, leading to inconsistencies in their ledgers.
Instead, you'd have to impose this logic in the flow. Let's say you have a TradeOffer flow that proposes a trade. Each node could install their own response flow that is initiated by TradeOffer flow. Each node's response flow could impose different conditions. For example, one node might sign any transaction, while another one would check that the proposed rate is within specified bounds.
To extend Joel's comment, the contract is indeed hard-coded, but there's nothing wrong with putting meta logic in there as long as the code runs the same way every time (i.e. it's deterministic).
What do I mean by this? Well, you can put a String type in your state which contains an expression that can then be evaluated (if you refer to https://relayto.com/r3/FIjS0Jfy/VB8epyay73 you can see the inclusion of a very basic maths expression used in a smart contract). There's nothing wrong with making this String as complex as possible, but just be aware that any potential users of your application will start raising eyebrows if you remove a lot of the protection that Corda offers of validation if you start dumbing down the coded verification logic and putting it all into a String.

How to use Drupal rules to adapt content access permissions for nodes that are older than 1 week?

I have a special content type named "example". I want to show new nodes of this type to anonymous users of my site.
What I need: after 1 week the node was created, content access permissions (Content Access module is installed) are changed that only users with particular role are able to see this node.
Should this be triggered on cron or what? Or just how to do something to nodes that are older than 1 week?
Could you provide some instructions on how to do that? Because I'm new to the Rules module and have no any ideas.
You should be able to do this with Rules (see this question, not exactly what you want but close), but I'd go for a tiny custom module implementing hook_cron, where you fetch all nodes with creation date < (now - 1 week), and modify the permissions for each of them.
It should be more efficient than the Rule approach explained in my first link, where you need to loop over all nodes on each cron execution. And Rules can be quite more annoying than writing plain PHP. I prefer learning Drupal API than spending hours clicking in Rules interface (Rules is great, but it's hard).
Good luck
Yes you should be able to get this to work using the Rules module to implement what you're looking for, but I recommend you to also combine that with the Rules Once per Day and the Views Rules modules, as further explained below.
Step 1: Rules Event
Your question doesn't really specify anything that could/should be used as the Rules Event (for the rule to be triggered. And even though it's like "up to your own imagination" (any Rules Event will do), something that will work for sure is to use the Rules Once per Day module. Here is how it works (as per the comment in issue 2495775, from the module owner):
You specify a trigger hour on the administration settings page for this module.
The Rule trigger will then run when cron tasks are first run after the start of that hour. The actual run time will depend on your cron task timings.
So this is another way to understand/read this:
The "Event" will only be triggered when a cron job is run.
And that event will only be triggered 1 time / day, i.e. "next time cron runs after the trigger hour has passed".
Step 2: Rules Actions (and optional events)
Some details about the Views Rules module (from its project page):
Provides Views directly as Rules actions and loops to seamlessly use view result data.
The previous quote may seem a bit cryptic (it may make you think like "so what, how can this help me?"). Therefor some more details about how to move forward using these modules:
Create a view (using Views) so that you have 1 Views result (row) with all the nodes (of at least 1 week old) you want to be processed, whereas that view has fields (columns) for whatever is needed in subsequent steps, eg the node ID, but possibly other fields as well. You'll need these View fields later on as values to be processed by your rule, "to change the content access permissions (using the content_access module) so that only users with particular role are able to see such nodes" (similar to what you mentioned in your question). Important: use a Views display type of "Rules".
Create a custom rule in which you use the Views Rules module to iterate over each of these Views results in a Rules action, using the Rules technique known as a "Rules Loop".
For each iteration step in your Rules loop, perform a Rules Action to "do your thing" (= change the content access permissions). At that point you'll have all data from each column of your Views results available as so called Rules Parameters. So at that point it's a piece of cake to adapt the content access permissions for the node you're processing in that loop.
Optionally, you may also want to add whatever extra Rules Condition(s), also up to your own imagination.
Easy, no?

installing rules in openflow

In Openflow, we install rules with priorities. Now suppose we already have two rules installed at a switch, of priority 1 and 2. And now we want to add another rule, of some priority strictly between 1 and 2 (say 1.5). What is the usual way to handle this scenario.
A standard practice used within networking and defining various rule lists (ACLs, etc) is to number them in increments of 10, so new rules can easily be injects between. The same could apply here.
Of course, with OpenFlow, it is trivial to completely replace all the rules. So you could simply just delete the existing ones and send out a new set of rules with the corrected priority values.

Resources