Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Routers and Selectors. Part 5 race #807

Open
emil14 opened this issue Dec 14, 2024 · 1 comment
Open

Routers and Selectors. Part 5 race #807

emil14 opened this issue Dec 14, 2024 · 1 comment
Assignees

Comments

@emil14
Copy link
Collaborator

emil14 commented Dec 14, 2024

Previous parts:

Race

Basic

Race is a router like if and switch. But like select it makes decisions based on message arrival order rather than message values. First it receives a message to route from data_sender, then it wait for the first condition sender to trigger and sends data message to selected reciver.

Race to Select is what Switch to Match

data_sender -> race {
    cond_sender1 -> receiver1
    cond_sender2 -> receiver2
    cond_sender3 -> receiver3
}

With Default Branch (Non-Blocking)

Unlike select race can include a default branch that receives messages when no condition sender has fired. This is because unlike select it does have a special inport that kicks it - without message from data-sender, there's nothing to route.

data_sender -> race {
    cond_sender1 -> receiver1
    cond_sender2 -> receiver2
    _ -> default_receiver
}

With Final Receiver

Like other routers, Race can have a final receiver. It receives a data message after selected branch receiver has received it

data_sender -> race {
    cond_sender1 -> receiver1
    cond_sender2 -> receiver2
} -> final_receiver

The message final receiver receive is of type RaceResult<T>

{
    data T  // data message
    idx int // 0-based index of the branch that was selected
}

Selector

Race, like other routers, has a selector-mode where it can choose both the message to send and the direction to send it. When used this way, its body must not be connected to a single data-sender, because all the data-senders are inside:

race {
    cond_sender1: data_sender1 -> receiver1
    cond_sender2: data_sender2 -> receiver2
}

This form can also include a final receiver, which receives the selected data message:

race {
    cond_sender1: data_sender1 -> receiver1
    cond_sender2: data_sender2 -> receiver2
} -> final_receiver

In that case it also receives a RaceResult with the selected data message and index of the selected branch.

Multiple Conditions and Receivers

Race supports multiple condition senders per branch and multiple receivers per branch. Multiple condition senders are treated as "one of" (first to fire wins), while multiple receivers create a fan-out pattern.

data_sender -> race {
    [cond_sender1, cond_sender2]: data_sender1 -> receiver1
    cond_sender3: data_sender2 -> [receiver2, receiver3]
    _ -> default_receiver
} -> final_receiver

As a Conditional Lock

Race covers simple pattern where there's only one direction to send, but several conditions to lock/unlock:

data_sender -> race {
    [cond_sender1, cond_sender2] -> receiver
}
@emil14
Copy link
Collaborator Author

emil14 commented Dec 14, 2024

Race selector without final receiver does exactly what N parallel deferred connections would do, so that form has no unique value

Upd: well deferred connections would have latency so... it's not really the same

Upd2: besides that, this race form will have even more sense if we allow incoming data sender and make branch data senders optional

@emil14 emil14 self-assigned this Dec 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant