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

Conntrack latency measurement recipe #376

Closed
wants to merge 6 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 55 additions & 3 deletions lnst/RecipeCommon/Perf/Results.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,43 @@ def end_timestamp(self):
def time_slice(self, start, end):
raise NotImplementedError()

class ScalarSample(PerfResult):
Copy link
Collaborator

Choose a reason for hiding this comment

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

not sure about this implementation considering it's still using duration and has time slicing.... at least this should be refactored so that the common PerfInterval and ScalarSample property getters are in some common class...

def __init__(self, value, unit, timestamp):
self._value = value
self._unit = unit
self._timestamp = timestamp

@property
def value(self):
return self._value

@property
def duration(self):
return 1 # just to make it compatible with other PerfInterval objects

@property
def unit(self):
return self._unit

@property
def start_timestamp(self):
return self._timestamp

@property
def end_timestamp(self):
return self._timestamp

def time_slice(self, start, end):
if end <= self.start_timestamp or start >= self.end_timestamp:
raise EmptySlice(
"current start, end {} {}; request start, end {}, {}".format(
self.start_timestamp, self.end_timestamp, start, end,
)
)

return ScalarSample(self.value, self.unit, self.start_timestamp)


class PerfInterval(PerfResult):
def __init__(self, value, duration, unit, timestamp):
self._value = value
Expand Down Expand Up @@ -110,7 +147,8 @@ def _validate_item(self, item):

def _validate_item_type(self, item):
if (not isinstance(item, PerfInterval) and
not isinstance(item, PerfList)):
not isinstance(item, PerfList) and
not isinstance(item, ScalarSample)):
raise LnstError("{} only accepts PerfInterval or PerfList objects."
.format(self.__class__.__name__))

Expand Down Expand Up @@ -165,7 +203,7 @@ def merge_with(self, iterable):
if type(val1) != type(val2):
raise LnstError("Cannot merge different types of PerfList objects.")

if isinstance(val1[0], PerfInterval):
if isinstance(val1[0], PerfInterval) or isinstance(val1[0], ScalarSample):
container = val1.__class__()
container.extend(val1)
container.extend(val2)
Expand Down Expand Up @@ -201,7 +239,7 @@ def samples_slice(self, slicer: callable):
if len(self) == 0:
raise EmptySlice("No samples to slice.")

if isinstance(self[0], PerfInterval):
if isinstance(self[0], PerfInterval) or isinstance(self[0], ScalarSample):
result.extend(self[slicer])
elif isinstance(self[0], PerfList):
for item in self:
Expand Down Expand Up @@ -234,6 +272,11 @@ def start_timestamp(self):
def end_timestamp(self):
return self[-1].end_timestamp


class SequentialScalarResult(SequentialPerfResult):
pass


class ParallelPerfResult(PerfList, PerfResult):
@property
def value(self):
Expand All @@ -260,6 +303,15 @@ def start_timestamp(self):
def end_timestamp(self):
return max([i.end_timestamp for i in self])


class ParallelScalarResult(ParallelPerfResult):
@property
def average(self):
samples_count = sum([len(i) for i in self])
Copy link
Collaborator

Choose a reason for hiding this comment

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

this won't work if:

ParallelScallarResult([ScalarSample, ...])

as ScalarSample doesn't support len


return self.value / samples_count


def result_averages_difference(a, b):
if a is None or b is None:
return None
Expand Down