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

Introducing the begin chain element #1072

Merged
merged 9 commits into from
Aug 31, 2021

Conversation

edwarnicke
Copy link
Member

@edwarnicke edwarnicke commented Aug 26, 2021

Description

Package begin provides a chain element that can be put at the beginning of the chain, after Connection.Id has been set
but before any chain elements that would mutate the Connection on the return path.
the begin.New{Client,Server}() guarantee:

Scope

All Request() or Close() events are scoped to a particular Connection, uniquely identified by its Connection.Id

Exclusivity

Only one event is processed for a Connection.Id at a time

Order

Events for a given Connection.Id are processed in the order in which they are received

Close Correctness

When a Close(Connection) event is received, begin will replace the Connection provided with the last Connection
successfully returned from the chain for Connection.Id

Midchain Originated Events

A midchain element may originate a Request() or Close() event to be processed
from the beginning of the chain (Timeout, Refresh,Heal):

errCh := begin.FromContext(ctx).Request()
errCh := begin.FromContext(ctx).Close()

errCh will receive any error from the firing of the event, and will be closed after the event has fully
processed.

Note: if a chain is a server chain continued by a client chain, the beginning of the chain is at the beginning of
the server chain, even if there is a subsequent begin.NewClient() in the client chain.

Optionally you may use the CancelContext(context.Context) option:

begin.FromContext(ctx).Request(CancelContext(cancelContext))
begin.FromContext(ctx).Close(CancelContext(cancelContext))

If cancelContext is cancelled prior to the processing of the event, the event processing will be skipped,
and the errCh returned simply closed.

Midchain Originated Request Event

Example:

begin.FromContext(ctx).Request()

will use the networkservice.NetworkServiceRequest from the chain's last successfully completed Request() event
with networkservice.NetworkServiceRequest.Connection replaced with the Connection returned by the chain's last
successfully completed Request() event

Chain Placement

begin.New{Server/Client} should always proceed any chain element which:

  • Maintains state
  • Mutates the Connection object along the return path of processing a Request() event.

Reasoning

networkservice.NetworkService{Client,Server} processes two kinds of events:

  • Request()
  • Close()
    Each Request() or Close() event is scoped to a networkservice.Connection, which can be uniquely identified by its Connection.Id

For a given Connection.Id, at most one event can be processed at a time (exclusivity).

For a given Connection.Id, events must be processed in the order they were received (order).

For Close(), the Connection passed to it must be identical to the last one returned by the chain to insure all state
is correctly cleared (close correctness).

Typically, a chain element receives a Request() or Close() event from the element before it in the chain
and sends a Request() or Close() and either terminates processing returning an error, or sends a Request() or Close()
event to the next element in the chain.

There are some circumstances in which a Request() or Close() event needs to be originated by a chain element
in the middle of the chain, but processed from the beginning of the chain. Examples include (but are not limited to):

  • A server timing out an expired Connection
  • A client refreshing a Connection so that it does not expire
  • A client healing from a lost Connection

In all of these cases, the Request() or Close() event should be processed starting at the beginning of the chain, to ensure
that all of the proper side effects occur within the chain.

Issue link

How Has This Been Tested?

  • Added unit testing to cover
  • Tested manually
  • Tested by integration testing
  • Have not tested

Types of changes

  • Bug fix
  • New functionallity
  • Documentation
  • Refactoring
  • CI

updatepath.NewClient("refresh"),
begin.NewClient(),
metadata.NewClient(),
injectclock.NewClient(clk),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A brief comment on why 'injectclock'. We are using mockClock to control time in our testing. The more I poked at this, the more I saw the benefit of it. That said, mockClock is inserted via the ctx. That works fine when the Request or Close event are coming from the outside, but midchain events do not preserve values from the ctx (by design), so it was necessary to have some what to inject the mockClock into the context before it was needed (say by refresh). injectclock is a small simple chain element that does that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

// `timeout` uses ctx as a context for the timeout Close and it closes only the subsequent chain, so
// chain elements before the `timeout` in chain shouldn't make any updates to the Close context and
// shouldn't be closed on Connection Close.
timeout.NewServer(ctx),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note... timeout's placement order in the chain no longer matters. As long as its after begin and metadata, it will work fine, because the Close() event it fires will start from begin.

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>
@edwarnicke edwarnicke force-pushed the beginagain branch 2 times, most recently from 27e4827 to 038cdd8 Compare August 27, 2021 05:06
ch := make(chan error, 1)
f.executor.AsyncExec(func() {
defer close(ch)
if f.state != established || f.client == nil || f.request == nil {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like next.Client(ctx) can return nil - it is either returns an instance of nextClient or tailClient, so do we need this check?

Suggested change
if f.state != established || f.client == nil || f.request == nil {
if f.state != established || f.request == nil {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a a bit paranoid... thus the extra nil check there :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in recent push

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still looks like not fixed :)
It actually even looks like f.state == established already means f.request != nil.

Copy link
Member Author

@edwarnicke edwarnicke Aug 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It actually even looks like f.state == established already means f.request != nil.

I don't follow, could you say more?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f.state becomes established only after the first successful Request, and it actually means that f.request == that successful Request.
All subsequent Requests can modify f.request, but not set it to nil.
All subsequent Closes will set f.state to closed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the latest push should fix this.

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>
Copy link
Member

@denis-tingaikin denis-tingaikin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a few comments

pkg/networkservice/common/begin/event_factory.go Outdated Show resolved Hide resolved
pkg/networkservice/common/begin/doc.go Show resolved Hide resolved
// go back to the beginning and try again.
currentConnClient, _ := b.LoadOrStore(request.GetConnection().GetId(), eventFactoryClient)
if currentConnClient != eventFactoryClient {
conn, err = b.Request(ctx, request)
Copy link
Member

@denis-tingaikin denis-tingaikin Aug 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel it can be super useful if we add logging on this branch because trace will not cover this call. Also each return statement can be covered by logging, that can help us to determine potential bugs by logs on ci.

pkg/networkservice/common/begin/server.go Show resolved Hide resolved
updatepath.NewClient("refresh"),
begin.NewClient(),
metadata.NewClient(),
injectclock.NewClient(clk),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>
edwarnicke added a commit to edwarnicke/sdk that referenced this pull request Aug 30, 2021
@denis-tingaikin denis-tingaikin merged commit 2e38282 into networkservicemesh:main Aug 31, 2021
nsmbot pushed a commit to networkservicemesh/sdk-kernel that referenced this pull request Aug 31, 2021
…k@main

PR link: networkservicemesh/sdk#1072

Commit: 2e38282
Author: Ed Warnicke
Date: 2021-08-31 03:56:01 -0500
Message:
  - Introducing the begin chain element (#1072)
* Introducing the begin chain element

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>

* Make metadata access functions private for refresh and timeout

Signed-off-by: Ed Warnicke <[email protected]>

* Simplify refresh/timeout cancel handling

In response to comment: networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Simplification in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Change in response to comment networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Improve logging in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: NSMBot <[email protected]>
nsmbot pushed a commit to networkservicemesh/cmd-nse-vfio that referenced this pull request Aug 31, 2021
…k@main

PR link: networkservicemesh/sdk#1072

Commit: 2e38282
Author: Ed Warnicke
Date: 2021-08-31 03:56:01 -0500
Message:
  - Introducing the begin chain element (#1072)
* Introducing the begin chain element

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>

* Make metadata access functions private for refresh and timeout

Signed-off-by: Ed Warnicke <[email protected]>

* Simplify refresh/timeout cancel handling

In response to comment: networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Simplification in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Change in response to comment networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Improve logging in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: NSMBot <[email protected]>
nsmbot pushed a commit to networkservicemesh/cmd-nse-icmp-responder that referenced this pull request Aug 31, 2021
…k@main

PR link: networkservicemesh/sdk#1072

Commit: 2e38282
Author: Ed Warnicke
Date: 2021-08-31 03:56:01 -0500
Message:
  - Introducing the begin chain element (#1072)
* Introducing the begin chain element

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>

* Make metadata access functions private for refresh and timeout

Signed-off-by: Ed Warnicke <[email protected]>

* Simplify refresh/timeout cancel handling

In response to comment: networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Simplification in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Change in response to comment networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Improve logging in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: NSMBot <[email protected]>
nsmbot pushed a commit to networkservicemesh/cmd-nsmgr-proxy that referenced this pull request Aug 31, 2021
…k@main

PR link: networkservicemesh/sdk#1072

Commit: 2e38282
Author: Ed Warnicke
Date: 2021-08-31 03:56:01 -0500
Message:
  - Introducing the begin chain element (#1072)
* Introducing the begin chain element

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>

* Make metadata access functions private for refresh and timeout

Signed-off-by: Ed Warnicke <[email protected]>

* Simplify refresh/timeout cancel handling

In response to comment: networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Simplification in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Change in response to comment networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Improve logging in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: NSMBot <[email protected]>
nsmbot pushed a commit to networkservicemesh/cmd-nsmgr that referenced this pull request Aug 31, 2021
…k@main

PR link: networkservicemesh/sdk#1072

Commit: 2e38282
Author: Ed Warnicke
Date: 2021-08-31 03:56:01 -0500
Message:
  - Introducing the begin chain element (#1072)
* Introducing the begin chain element

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>

* Make metadata access functions private for refresh and timeout

Signed-off-by: Ed Warnicke <[email protected]>

* Simplify refresh/timeout cancel handling

In response to comment: networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Simplification in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Change in response to comment networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Improve logging in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: NSMBot <[email protected]>
nsmbot pushed a commit to networkservicemesh/cmd-registry-proxy-dns that referenced this pull request Aug 31, 2021
…k@main

PR link: networkservicemesh/sdk#1072

Commit: 2e38282
Author: Ed Warnicke
Date: 2021-08-31 03:56:01 -0500
Message:
  - Introducing the begin chain element (#1072)
* Introducing the begin chain element

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>

* Make metadata access functions private for refresh and timeout

Signed-off-by: Ed Warnicke <[email protected]>

* Simplify refresh/timeout cancel handling

In response to comment: networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Simplification in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Change in response to comment networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Improve logging in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: NSMBot <[email protected]>
nsmbot pushed a commit to networkservicemesh/sdk-k8s that referenced this pull request Aug 31, 2021
…k@main

PR link: networkservicemesh/sdk#1072

Commit: 2e38282
Author: Ed Warnicke
Date: 2021-08-31 03:56:01 -0500
Message:
  - Introducing the begin chain element (#1072)
* Introducing the begin chain element

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>

* Make metadata access functions private for refresh and timeout

Signed-off-by: Ed Warnicke <[email protected]>

* Simplify refresh/timeout cancel handling

In response to comment: networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Simplification in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Change in response to comment networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Improve logging in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: NSMBot <[email protected]>
nsmbot pushed a commit to networkservicemesh/cmd-registry-memory that referenced this pull request Aug 31, 2021
…k@main

PR link: networkservicemesh/sdk#1072

Commit: 2e38282
Author: Ed Warnicke
Date: 2021-08-31 03:56:01 -0500
Message:
  - Introducing the begin chain element (#1072)
* Introducing the begin chain element

Please read pkg/networkservice/common/begin/doc.go
for extensive documentation.

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>

* Make metadata access functions private for refresh and timeout

Signed-off-by: Ed Warnicke <[email protected]>

* Simplify refresh/timeout cancel handling

In response to comment: networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Simplification in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Change in response to comment networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

* Update pkg/networkservice/common/begin/event_factory.go

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Denis Tingaikin <[email protected]>
Signed-off-by: Ed Warnicke <[email protected]>

* Improve logging in response to networkservicemesh/sdk#1072 (comment)

Signed-off-by: Ed Warnicke <[email protected]>

Co-authored-by: Vladimir Popov <[email protected]>
Signed-off-by: NSMBot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants