Trouble with sending some quantity forward in the process, and looping back - bpmn

The process in a nutshell is that we are trying to recruit for open positions. We are assuming there is more than one position to be filled. There are level 1 & level 2 interviews, if someone passes, we want them to continue forward of course. But if not enough people pass to fill all of the open positions, we still need the ones who did succeed to move forward, while starting the searching process over again.
My question is, is how do I close off this process when there are multiple people/units/flows moving through it? Is the circled exclusive gateway at the end enough?

The exclusive gateway at the end of the process is correct.
However, I think the upper part of your diagramme might need some clarification. I see two design choices that you might want to rethink:
Does the Search for Candidates task create a list of candidates to interview or a single candidate ? In your diagramme, it first looks like there is a list of candidates that get interviewed in parallel during the Level 1 Interview task. However, the subsequent gateway suggests that you decide for each candidate, whether he/she has passed that level. If not, you move back to searching. The same applies for the Level 2 Interview task.
The inclusive gateways also suggest that you are deciding on individual candidates, whether they have passed each level because you can have a Yes and a No at the same time.
If a search for candidates results in a list of candidates that get interviewed at the same time, then I would put the interviews and Assign to project tasks inside a sub-process. You would loop through the interviews and assigning tasks until all posts are filled or all candidates examined (note the exit condition in the annotation at the top). If one round of interviews has not filled all posts, you would decide whether you need to launch another round.
If you rather interview candidates individually and want to avoid a sub-process, then you could keep your structure but use exclusive instead of inclusive gateways:
Note the data items in both examples that make it explicit whether your search resulted in a list of candidates that get interviewed or a single candidate at a time.

Related

BPMN Intermediate Events Attached to an Activity Boundary

how would you drow diagram - example A or Example B or both are fine? In Example A there is an event, one extra task and process is back in the main flow. Example B - if the event occurs process is not back in main flow. Is it correct to draw process like in example A? Examples enclosed. Thank you in advance for help.
I draw examples (enclosed) and checked in BPMN specification but still have doubs.
I would go a step further and put a gateway in front of "Application Analysis" and then draw the arrow from the message event to that gateway (so the gateway is only used to join, doesn't need a condition, it is best practice, you could draw the arrow from the message event directly back on the task itself and it would express the same thing).
The basic reasoning is that you shouldn't have multiple tasks for the same thing in the diagram unless it is really at a different stage in the workflow.
However it isn't exactly the same as your workflow, because like this the customer could change the loan amount multiple times and not just once.
There are some problems:
I think you want to make the message event interrupting, otherwise you grant both loans, the original one and the changed one.
After "Application Analysis" there should probably be a gateway that checks the result of the analysis and only if it was ok you grant the loan.

Correct way to diagram a BPMN loop process with more than one condition

Most of the examples of BPMN representing loop processes use the example of a single task with a single condition, such as the one in a previous question.
However, I am struggling a little bit to understand how you might do this for a task that has two conditions (which might also mean that it needs to be broken up into multiple tasks?).
The example I will provide is this:
A person needs to send a message to someone and make sure that it has been received (task 1) so they can move onto the next step (task 2). But if they send the same message out three times with no response then they will take another action (task 3). So the two conditions for task 1 is that a confirmation has been provided by the receiver (condition A) and that the message has not been sent out three times yet (condition B).
Hopefully someone with more experience can help with an example or a better way to represent this logic.
I would recommend not to model the repeated sending of messages as a loop. This is not an actual part of the business process, but probably rather a general communcation strategy in your system (and therefore valid for all sending operations).
If you do want to emphazize this behavior at this point, you could use an annotation.
So something like this should be fine and understandable:

What are the errors in this BPMN?

I have a BPMN diagram (see below) with some errors that I can't seem to figure out. The diagram depicts the Produce Magazine Article Process, where the writer and Researcher are freelancers who work together to write articles for various publications.
Bigger version: BPMN diagram
There is a bunch of errors here, three of them are logical (two are related), one is BPMN syntax.
Let's start with the syntax.
The message is always a communication between two separate pools s it has to cross pool boundaries. In your case, you have depicted Freelancers as a single pool, so Send information, being between lanes but not pools is a syntax error. Before suggesting a solution though, I will focus on logical errors.
Time event is not used to show the fact that some time goes by between the activities. That is actually something natural in the process It is used to indicate that the flow of time is a trigger of the next action(s). For instance, 7 days after choosing a topic the Publication might contact the Researcher to check on the progress. That would be indicated by timed event. In your case, it seems that the flow continuation is triggered by passing messages so you should indicate it as an Incoming message event. You actually do that in 2 places, one that is obvious (Get article as a "result" of time event) and the second that correlates to a second problem.
The second thing that most probably is a logical question is that since we are talking here about freelancers, most probably Researcher and Writer are two separate entities, not one organisation as your current diagram suggests. If that is the case, you should have them represented as two separate pools. Then your message would be judged, but still rather than "Wait for information" time event you should have "Receive information" incoming message event (that is BTW the starting event for the Writer pool - similarly receiving Article request by Researcher should be handled by Incoming message event).
If you prefer to depict the Freelancer as one "organisation", then you should completely abandon the time event (as again you have used it as an indication of time passing and as I have explained earlier that is not how it should be used). You have a simple flow, where once Researcher finishes their job, it is passed to Writer who carries it over from there. In such case, you should have a simple action flow (solid line) between the actions themselves.
It is also a good practice to be consistent in using End events (and at least recommended - some BPM engines verify that) to always have an End even for every branch of a process. You are missing one or two, depending on how are you going to approach the Freelancers part. Similarly, you should have a Start event for Publication.
Below are the two options shown in the form of diagrams. Note that I also did some minor changes to handle the insufficient information case by Publication. Otherwise, they will be stuck forever waiting for the article to come.
Option with Freelancers as separate pools:
Option with Freelancers considered as a single organisation

RabbitMQ - How to ensure two queues stay synchronized

I have two queues that both have distinct data types that affect one another as they're being processed by my application, therefore processing messages from the two queues asynchronously would cause a data integrity issue.
I'm curious as to the best practice for making sure only one consumer is consuming at any given time. Here is a summary of what I have so far:
EventMessages receive information about external events that may or may not have an impact on the enqueued/existing PurchaseOrderMessages.
Since we anticipate we'll be consuming more PurchaseOrderMessage than EventMessage, maybe we should just ensure the EventMessage Queue is empty (via the API) before we process anything in PurchaseOrderMessage Queue - but that gets into the question of wait times, etc. and this all needs to happen as close to real time as possible.
If there's a way to simply pause a Consumer A until Consumer B is at rest that might be the simplest solution, I'm just not quite sure which direction I need to go in.
UPDATE
To provide some additional context, a PurchaseOrderMessage will contain a Origin and Destination.
A EventMessage also contains location data.
Each time a PurchaseOrderMessage is processed, it will query the current EventMessage records for any Event locations that match the Origin and Destination of that PurchaseOrder and create an association.
Each time an EventMessage is processed, it will query the current PurchaseOrderMessage records for any Origins of Destinations that match that Event and create an association.
If synchronous queues aren't a good solution, what's an alternative that would insure none of the associations are missed when EventMessages and PurchaseOrderMessages are getting published to the app at the same time?
UPDATE 2
Ultimately this data will serve a UI which will have a list of PurchaseOrders and the events that might be affecting their delivery dates. It would be too slow to do the "Event Check" as the PurchaseOrder data was being rendered/retrieved by the end user which is why we're wanting to do it as they're processed/consumed.
Let me begin with the bottom line up front - on the face of it, what you are asking doesn't make sense.
Queues should never require synchronization. The very thought of doing so entirely defeats the purpose of having a queue. For some background, visit this answer.
Let's consider some common places from real life where we encounter multiple queues:
Movie theaters (box office, concession counter, usher)
Theme parks (snack bars, major attractions)
Manufacturing floors (each station may have a queue waiting to process)
In each of these examples, from the point of view of the object in the queue, it can only wait in one at a time. It cannot wait in one line while it is waiting in another- such a thing is physically impossible.
Your example seems to take two completely unrelated things and merge them together. You have a queue for PurchaseOrder objects - but what is the queue for? That's the equivalent of going to Disney World and waiting in the Customer queue - what is the purpose of such a queue? If the purpose is not clear, it's not a real queue.
Addressing your issue
This particular issue needs to be addressed first by clearly defining the various operations that are being done to a PurchaseOrder, then creating queues for each of those operations. If these operations are truly synchronous, then your business logic should be coded to wait for one operation to complete before starting another. In this circumstance, it would be considered an exception if a PurchaseOrder got to the head of one queue without fulfilling a pre-requisite.
Please remember that a message queue typically serves a stateless operation. Good design dictates that messages in the queue contain all the information needed for the processor to process the message. If you don't adhere to this, then your database becomes a single point of contention for your system - and while this is not an insurmountable problem, it does make the design more complex.
Waiting in Multiple Queues
Now, if you've ever been to Disney World, you'll also know that they have something called a FastPass+ (FP+), which allows the holder to skip the line at the designated attraction. Disney allocates a certain number of slots per hour for each major attraction at the park, and guests are able to request up to three FP+s during each day. FP+ times are allocated for one hour blocks, and guests cannot have two overlapping FP+ time blocks. Once all FP+ slots have been issued for the ride, no more are made available. The FP+ system ensures these rules are enforced, independently of the standby queues for each ride. Essentially, by using FastPass+, guests can wait in multiple lines virtually and experience more attractions during their visit.
If you are unable to analyze your design and come up with an alternative, perhaps the FastPass+ approach could help alleviate some of the bottlenecks.
Disclaimer: I don't work for Disney, but I do go multiple times per month, always getting my FastPass first

Best way to handle read/unread messages in Redis activity feed?

I have an activity feed system that uses Redis sorted sets.
Events happen and a message is placed into a sorted set for each relevant user, with a timestamp for the score.
The messages are then distributed to the users, either when they log in, or through a push if the user is currently logged in.
I'd like to differentiate between messages that have been "read" by the user and ones that are still unread.
From my understanding, I can't just have a "read/unread" property as part of the member as changing it would cause the member to be different and therefore be added a second time, instead of replacing the current member.
So, what I'm thinking is that for each user, I have to sorted sets - an "unread" set and a "read" set.
When new events come in, they're added to the "unread" set
When the user reads a message, I add the message to the read set and remove it from the unread set.
A little less sure on how to deliver them. I can't just union them as I lose the distinction between read/unread unless I inverse the score on the unread ones, for instance.
Returning the two sets individually (and merging them in code) makes paging difficult. I'd like to be able to the 20 most recent messages regardless of read/unread status.
So, questions:
Is the read set/unread set way the best way to do it? Is there a better way?
What's the best way to return subsets of the merged/union'd data.
Thanks!
Instead of trying to update the member, you could just pop it and insert a new version. Should be no problem, because you know both member and its timestamp.