Skip to content

Commit

Permalink
Merge tag 'v14.4.0' into neo-v0.x.x
Browse files Browse the repository at this point in the history
Features
--------

`dhtproto.client.legacy.internal.helper.NodeAvailability`

This helper is useful in apps that have a data flow pattern like the following:
    1. Receive a record from an incoming source (e.g. a DMQ channel).
    2. Do some expensive but non-critical processing on the record. (e.g.
       querying an external service.)
    3. Write the results of the processing to the DHT.

By tracking which DHT nodes have had connectivity problems recently, the app
can decide to not perform step 2 at all, if the DHT node to which the result
would be written is inaccessible. (i.e. discarding the request, rather than
queuing up the write to be performed when the DHT node becomes accessible.)

`turtle.env.Dht`

App test suites typically need to wait for mirror/listen requests to start
before running any tests. To support this, the new method `Dht.expectListeners`
provides a means for waiting until a specified number of listeners are
registered with a specified list of channels. This allows app test suites to
implement test cases which would validate the mirror setup.

* `dhtproto.client.legacy.internal.request.model.IBulkGetRequest`
* `dhtproto.client.legacy.internal.request.params.RequestParams`

This new delegate should be used to remove an ISuspendable
instance from a list of ISuspendables when a request finishes.
  • Loading branch information
matthias-wende-sociomantic committed Nov 23, 2018
2 parents 89df043 + 253f58f commit 7a1bbf0
Show file tree
Hide file tree
Showing 115 changed files with 485 additions and 142 deletions.
2 changes: 0 additions & 2 deletions README.rst
Expand Up @@ -68,11 +68,9 @@ Maintained Major Branches
======= ==================== =============== =====
Major Initial release date Supported until Notes
======= ==================== =============== =====
v13.x.x v13.0.0_: 01/08/2017 30/07/2018 First open source release
v14.x.x v14.0.0_: 30/01/2018 TBD
======= ==================== =============== =====

.. _v13.0.0: https://github.com/sociomantic-tsunami/dhtproto/releases/tag/v13.0.0
.. _v14.0.0: https://github.com/sociomantic-tsunami/dhtproto/releases/tag/v14.0.0


Expand Down
2 changes: 1 addition & 1 deletion integrationtest/dhtrestart/main.d
Expand Up @@ -5,7 +5,7 @@
start listening on "test_channel1" and push all records to "test_channel2".
Copyright:
Copyright (c) 2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion integrationtest/env/main.d
Expand Up @@ -4,7 +4,7 @@
application
Copyright:
Copyright (c) 2016-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2016-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion integrationtest/fakedht/main.d
Expand Up @@ -3,7 +3,7 @@
Runs dhttest on a fake DHT node instance.
Copyright:
Copyright (c) 2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
15 changes: 15 additions & 0 deletions relnotes/avail.feature.md
@@ -0,0 +1,15 @@
### New legacy client tracker for node availability

`dhtproto.client.legacy.internal.helper.NodeAvailability`

This helper is useful in apps that have a data flow pattern like the following:
1. Receive a record from an incoming source (e.g. a DMQ channel).
2. Do some expensive but non-critical processing on the record. (e.g.
querying an external service.)
3. Write the results of the processing to the DHT.

By tracking which DHT nodes have had connectivity problems recently, the app
can decide to not perform step 2 at all, if the DHT node to which the result
would be written is inaccessible. (i.e. discarding the request, rather than
queuing up the write to be performed when the DHT node becomes accessible.)

10 changes: 10 additions & 0 deletions relnotes/expectlisteners.feature.md
@@ -0,0 +1,10 @@
### New method to wait until a certain number of listeners are registered

`turtle.env.Dht`

App test suites typically need to wait for mirror/listen requests to start
before running any tests. To support this, the new method `Dht.expectListeners`
provides a means for waiting until a specified number of listeners are
registered with a specified list of channels. This allows app test suites to
implement test cases which would validate the mirror setup.

7 changes: 7 additions & 0 deletions relnotes/unregister_requestsuspender.feature.md
@@ -0,0 +1,7 @@
### Add delegate to unregister RequestSuspender

* `dhtproto.client.legacy.internal.request.model.IBulkGetRequest`
* `dhtproto.client.legacy.internal.request.params.RequestParams`

This new delegate should be used to remove an ISuspendable
instance from a list of ISuspendables when a request finishes.
2 changes: 1 addition & 1 deletion src/dhtproto/client/DhtClient.d
Expand Up @@ -106,7 +106,7 @@
-debug=Raw: trace outputs noting raw data sent & received via epoll
Copyright:
Copyright (c) 2011-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2011-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion src/dhtproto/client/legacy/DhtConst.d
Expand Up @@ -3,7 +3,7 @@
Dht Client & Node Constants
Copyright:
Copyright (c) 2009-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2009-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion src/dhtproto/client/legacy/common/NodeRecordBatcher.d
Expand Up @@ -4,7 +4,7 @@
dht nodes.
Copyright:
Copyright (c) 2014-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2014-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion src/dhtproto/client/legacy/internal/DhtClientExceptions.d
Expand Up @@ -3,7 +3,7 @@
Custom exception types which can be thrown inside a dht client.
Copyright:
Copyright (c) 2011-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2011-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion src/dhtproto/client/legacy/internal/RequestSetup.d
Expand Up @@ -3,7 +3,7 @@
Mixins for request setup structs used in DhtClient.
Copyright:
Copyright (c) 2011-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2011-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
Expand Up @@ -3,7 +3,7 @@
Pool of dht node socket connections holding IRequest instances
Copyright:
Copyright (c) 2011-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2011-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
Expand Up @@ -3,7 +3,7 @@
DHT node socket connection holding Request instances
Copyright:
Copyright (c) 2010-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2010-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
Expand Up @@ -4,7 +4,7 @@
resources by active request handlers.
Copyright:
Copyright (c) 2012-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2012-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
Expand Up @@ -3,7 +3,7 @@
Information about a dht connection pool
Copyright:
Copyright (c) 2011-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2011-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion src/dhtproto/client/legacy/internal/helper/ChannelMirror.d
Expand Up @@ -8,7 +8,7 @@
Usage example below.
Copyright:
Copyright (c) 2011-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2011-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
Expand Up @@ -12,7 +12,7 @@
these plugins.
Copyright:
Copyright (c) 2016-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2016-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion src/dhtproto/client/legacy/internal/helper/GroupRequest.d
Expand Up @@ -45,7 +45,7 @@
---
Copyright:
Copyright (c) 2012-2017 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2012-2017 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion src/dhtproto/client/legacy/internal/helper/Handshake.d
Expand Up @@ -3,7 +3,7 @@
Class to perform a handshake with all DHT nodes (retrying when it fails),
providing task helpers that block until one or all nodes are connected.
Copyright: Copyright (c) 2018 sociomantic labs GmbH. All rights reserved
Copyright: Copyright (c) 2018 dunnhumby Germany GmbH. All rights reserved
License: Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
2 changes: 1 addition & 1 deletion src/dhtproto/client/legacy/internal/helper/Mirror.d
Expand Up @@ -11,7 +11,7 @@
The receiveRecord method is abstract and must be implemented by the user.
Copyright:
Copyright (c) 2018 sociomantic labs GmbH. All rights reserved.
Copyright (c) 2018 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
Expand Down
195 changes: 195 additions & 0 deletions src/dhtproto/client/legacy/internal/helper/NodeAvailability.d
@@ -0,0 +1,195 @@
/*******************************************************************************
Tracker for availability of nodes, based on recency of connection errors.
This helper is useful in apps that have a data flow pattern like the
following:
1. Receive a record from an incoming source (e.g. a DMQ channel).
2. Do some expensive but non-critical processing on the record. (e.g.
querying an external service.)
3. Write the results of the processing to the DHT.
By tracking which DHT nodes have had connectivity problems recently, the app
can decide to not perform step 2 at all, if the DHT node to which the result
would be written is inaccessible. (i.e. discarding the request, rather than
queuing up the write to be performed when the DHT node becomes accessible.)
Copyright:
Copyright (c) 2018 dunnhumby Germany GmbH. All rights reserved.
License:
Boost Software License Version 1.0. See LICENSE.txt for details.
*******************************************************************************/

module dhtproto.client.legacy.internal.helper.NodeAvailability;

/// ditto
public struct NodeAvailabilty
{
import swarm.Const;
import core.sys.posix.time;
import dhtproto.client.legacy.internal.registry.model.IDhtNodeRegistryInfo;

/// The number of seconds for which the `available()` methods will report a
/// node as inaccessible after an error is reported for it.
public uint retry_delay_s = 3;

/***************************************************************************
Should be called when a request to the specified node fails due to a
connection error.
Params:
node = node that had a connection error
***************************************************************************/

public void error ( NodeItem node )
{
if ( auto tracker = node.toHash() in this.error_trackers )
{
tracker.error();
}
else
{
auto tracker = NodeErrorTracker(this);
tracker.error();
this.error_trackers[node.toHash()] = tracker;
}
}

/***************************************************************************
Tells whether the node that is responsible for the specified key is
believed to be currently accessible or not.
Params:
key = key of record to be accessed
registry = node registry to look up which node is responsible for
the specified key
Returns:
true if the node is believed to be accessible; false if it has had a
connection error recently
***************************************************************************/

public bool available ( hash_t key, IDhtNodeRegistryInfo registry )
{
auto node = registry.responsibleNode(key);
if ( node is null )
return false;

NodeItem nodeitem;
nodeitem.Address = node.address;
nodeitem.Port = node.port;

return available(nodeitem);
}

/***************************************************************************
Tells whether the specified node is believed to be currently accessible
or not.
Params:
node = node to be accessed
Returns:
true if the node is believed to be accessible; false if it has had a
connection error recently
***************************************************************************/

public bool available ( NodeItem node )
{
if ( auto tracker = node.toHash() in this.error_trackers )
return tracker.available();
else
return true;
}

/// Internal error tracker for a single node.
private struct NodeErrorTracker
{
/// Pointer to the outer instance.
NodeAvailabilty* outer;

/// Timestamp of last reported connection error.
private time_t last_error_timestamp;

/***********************************************************************
Should be called when a request to this node fails due to a
connection error.
***********************************************************************/

public void error ( )
{
this.last_error_timestamp = time();
}

/***********************************************************************
Tells whether the node is believed to be currently accessible or
not.
Returns:
true if the node is believed to be accessible; false if it has
had a connection error recently
***********************************************************************/

public bool available ( )
{
auto diff = time() - this.last_error_timestamp;
return diff >= this.outer.retry_delay_s;
}

/***********************************************************************
Returns:
the current timestamp
***********************************************************************/

private static time_t time ( )
{
timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return t.tv_sec;
}
}

/// Map of error trackers by node hash.
private NodeErrorTracker[hash_t] error_trackers;
}

version ( UnitTest )
{
import ocean.core.Test;
import swarm.Const;
}

unittest
{
auto n1 = NodeItem("addr".dup, 100);
auto n2 = NodeItem("addr".dup, 200);
NodeAvailabilty tracker;

test(tracker.available(n1));
test(tracker.available(n2));

tracker.error(n1);
test(!tracker.available(n1));
test(tracker.available(n2));

// Hack the last error timestamp so that it looks like the required delay
// has expired. (This saves us having to actually wait.)
tracker.error_trackers[n1.toHash].last_error_timestamp -=
tracker.retry_delay_s;
test(tracker.available(n1));
test(tracker.available(n2));
}

0 comments on commit 7a1bbf0

Please sign in to comment.