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

feat(api): add api function to register tracepoint directly #8

Merged
merged 3 commits into from
Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
29 changes: 28 additions & 1 deletion src/deep/api/deep.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
from typing import Dict, List

from deep.api.plugin import load_plugins
from deep.api.resource import Resource
from deep.api.tracepoint import TracePointConfig
from deep.config import ConfigService
from deep.config.tracepoint_config import TracepointConfigService
from deep.grpc import GRPCService
from deep.poll import LongPoll
from deep.processor import TriggerHandler
Expand All @@ -25,7 +29,7 @@ class Deep:
DEEP is so small there is no need for service injection work.
"""

def __init__(self, config):
def __init__(self, config: 'ConfigService'):
self.started = False
self.config = config
self.grpc = GRPCService(self.config)
Expand All @@ -51,3 +55,26 @@ def shutdown(self):
return
self.task_handler.flush()
self.started = False
def register_tracepoint(self, path: str, line: int, args: Dict[str, str] = None,
watches: List[str] = None) -> 'TracepointRegistration':
if watches is None:
watches = []
if args is None:
args = {}
tp_config = self.config.tracepoints.add_custom(path, line, args, watches)
return TracepointRegistration(tp_config, self.config.tracepoints)


class TracepointRegistration:
_cfg: TracePointConfig
_tpServ: TracepointConfigService

def __init__(self, cfg: TracePointConfig, tracepoints: TracepointConfigService):
self._cfg = cfg
self._tpServ = tracepoints

def get(self) -> TracePointConfig:
return self._cfg

def unregister(self):
self._tpServ.remove_custom(self._cfg)
23 changes: 22 additions & 1 deletion src/deep/config/tracepoint_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@

import abc
import logging
import uuid
from typing import Dict, List

from deep.api.tracepoint import TracePointConfig


class TracepointConfigService:
"""This service deals with new responses from the LongPoll"""

def __init__(self) -> None:
self._custom = []
self._tracepoint_config = []
self._current_hash = None
self._last_update = 0
Expand All @@ -43,6 +48,10 @@ def update_new_config(self, ts, new_hash, new_config):
self._last_update = ts
self._current_hash = new_hash
self._tracepoint_config = new_config
self.trigger_update(old_hash, old_config)

def trigger_update(self, old_hash, old_config):
ts = self._last_update
if self._task_handler is not None:
future = self._task_handler.submit_task(self.update_listeners, self._last_update, old_hash,
self._current_hash, old_config, self._tracepoint_config)
Expand All @@ -57,7 +66,7 @@ def update_listeners(self, ts, old_hash, current_hash, old_config, new_config):
listeners_copy = self._listeners.copy()
for listeners in listeners_copy:
try:
listeners.config_change(ts, old_hash, current_hash, old_config, new_config)
listeners.config_change(ts, old_hash, current_hash, old_config, new_config + self._custom)
except Exception:
logging.exception("Error updating listener %s", listeners)

Expand All @@ -73,6 +82,18 @@ def current_config(self):
def current_hash(self):
return self._current_hash

def add_custom(self, path: str, line: int, args: Dict[str, str], watches: List[str]) -> TracePointConfig:
config = TracePointConfig(str(uuid.uuid4()), path, line, args, watches)
self._custom.append(config)
self.trigger_update(None, None)
return config

def remove_custom(self, config: TracePointConfig):
for idx, cfg in enumerate(self._custom):
if cfg.id == config.id:
del self._custom[idx]
return


class ConfigUpdateListener(abc.ABC):
"""
Expand Down