Skip to content

Add bulk program attachment helpers #38

@gregclermont

Description

@gregclermont

Description

Both network_tracker.py and process_tracker.py contain similar boilerplate for attaching all programs and managing their links:

self._links = []
for name, prog in self.obj.programs.items():
    print(f"  Attaching {name} ({prog.section})...")
    try:
        link = prog.attach()
        self._links.append(link)
    except tinybpf.BpfError as e:
        print(f"    Warning: Could not attach {name}: {e}")

# Later, in cleanup:
for link in self._links:
    link.destroy()

This pattern is verbose and easy to get wrong (forgetting to destroy links, not handling errors consistently).

Proposed API

1. BpfObject.attach_all()

# Basic usage - raises on first error
links = obj.attach_all()

# With error handling - returns list of (name, link_or_exception) tuples
results = obj.attach_all(ignore_errors=True)
for name, result in results:
    if isinstance(result, Exception):
        print(f"Warning: {name} failed: {result}")
    else:
        print(f"Attached {name}")

# Get only successful links
links = [r for name, r in results if not isinstance(r, Exception)]

2. LinkCollection Context Manager

class LinkCollection:
    """Manages multiple BpfLinks with automatic cleanup."""
    
    def __init__(self, links: list[BpfLink]):
        self._links = list(links)
    
    def __enter__(self):
        return self
    
    def __exit__(self, *args):
        for link in self._links:
            link.destroy()
    
    def __iter__(self):
        return iter(self._links)
    
    def __len__(self):
        return len(self._links)

Usage:

with LinkCollection(obj.attach_all()) as links:
    print(f"Attached {len(links)} programs")
    # ... run event loop ...
# All links automatically destroyed

3. Combined: attach_all() returns LinkCollection

with obj.attach_all() as links:  # returns LinkCollection
    rb.poll()
# Auto-cleanup

Benefits

  1. Less boilerplate - common pattern becomes one line
  2. Correct resource cleanup - context manager ensures links are destroyed
  3. Consistent error handling - ignore_errors flag for partial attachment
  4. Discoverable - users find it via obj. autocomplete

Implementation Notes

  • attach_all() iterates obj.programs.values() and calls prog.attach()
  • LinkCollection is a simple wrapper with __enter__/__exit__
  • Could also add links.destroy_all() for manual cleanup
  • Consider making it iterable for for link in links: patterns

Related

This would simplify the examples and reduce copy-paste errors when users write their own trackers.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions