Skip to content

call monitor on container creation#4371

Open
anonrig wants to merge 3 commits intomainfrom
yagiz/call-monitor-on-destroy
Open

call monitor on container creation#4371
anonrig wants to merge 3 commits intomainfrom
yagiz/call-monitor-on-destroy

Conversation

@anonrig
Copy link
Member

@anonrig anonrig commented Jun 18, 2025

Addresses #4362 from a different perspective

Used AI to generate the tests.

Copy link
Member

@kentonv kentonv left a comment

Choose a reason for hiding this comment

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

Most applications will have called monitor() themselves, making this call redundant at best and possibly leading to inconsistent state.

The underlying problem is that if an application does not call monitor(), then the running boolean isn't updated when the container exits. This is actually independent of destroy(), but destroy() is one way to cause the inconsistency.

What we actually need to do is make a call to monitor() automatically internally, so that we can keep the running boolean accurate. The JS monitor() method will have to piggy-back on the internal call's result.

@kentonv
Copy link
Member

kentonv commented Jun 18, 2025

What we actually need to do is make a call to monitor() automatically internally, so that we can keep the running boolean accurate. The JS monitor() method will have to piggy-back on the internal call's result.

To clarify, we should call monitor() automatically in start() (or in the constructor, if the container is already running).

@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch from 8c5b79f to 7cba1d2 Compare June 18, 2025 17:27
@anonrig anonrig requested a review from kentonv June 18, 2025 17:27
@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch from 7cba1d2 to d6d3d08 Compare June 18, 2025 17:29
@anonrig anonrig changed the title call monitor on container destroy call monitor on container creation Jun 18, 2025
@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch from d6d3d08 to d1ef96f Compare June 18, 2025 17:35
@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch from d1ef96f to f9861d7 Compare June 18, 2025 17:39
@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch from f9861d7 to 00733e7 Compare June 26, 2025 20:00
@anonrig anonrig requested a review from kentonv June 26, 2025 20:00
@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch from 00733e7 to bdf8348 Compare July 9, 2025 14:27
@anonrig
Copy link
Member Author

anonrig commented Jul 9, 2025

@kentonv This is ready for another round of reviews. Would you mind taking a look?

Copy link
Member

@kentonv kentonv left a comment

Choose a reason for hiding this comment

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

I don't see any tests in this PR nor a PR to the internal codebase modifying the test there. Where is the new functionality tested?

@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch 2 times, most recently from 0932785 to 01dfc58 Compare February 27, 2026 14:34
@codspeed-hq

This comment was marked as off-topic.

@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch 2 times, most recently from 5aa78e6 to b17d89c Compare February 27, 2026 15:25
@anonrig anonrig requested review from jasnell and kentonv February 27, 2026 15:25
@anonrig anonrig requested a review from gabivlj February 27, 2026 15:26
// The background monitor promise, held to keep it alive. Uses eagerlyEvaluate()
// to ensure it runs to completion. Held here (rather than via addTask()) to avoid
// preventing DO hibernation.
kj::Maybe<IoOwn<kj::Promise<void>>> backgroundMonitor;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Eventually, it might be nice to bundle all the IoOwns into a struct so that there's just one IoOwn in use. Non-blocking for this tho.

Copy link
Collaborator

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

AI Review Summary

Findings posted as inline comments. Two additional items not pinned to diff lines:

  • visitForMemoryInfo not updated: The PR adds monitorState, monitorKjPromise, monitorJsPromise, and backgroundMonitor but doesn't update visitForMemoryInfo() to track them. Memory profiling will undercount the Container object's true size.

  • Missing test coverage for destroy() + active background monitor: If destroy() is called while the background monitor is running, the capnp docs say "If a call to monitor() is waiting when destroy() is invoked, monitor() will also return (with no error)." This edge case isn't exercised by the test suite.


This review was generated by an AI assistant and may contain inaccuracies. Please verify the findings independently.

@anonrig anonrig force-pushed the yagiz/call-monitor-on-destroy branch from b17d89c to 32150f7 Compare February 27, 2026 20:46
cmd.set(idx++, "--disable-ipv6");
}
cmd.set(idx++, "--address");
cmd.set(idx++, address);
Copy link
Contributor

Choose a reason for hiding this comment

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

this is going to break in some MacOS docker desktops as they dont have v6 enabled altogether. Thats why I decided against creating a network ourselves as it's complicated to accommodate all use-cases,

// Promise that resolves when the current start() RPC completes. The background
// monitor chains after this to avoid racing with the start RPC (which creates/
// starts the container). Without this, the monitor RPC's Docker /wait could see
// a stale container from a previous run and return its old exit code.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is an impl. detail of the container service. I think it should be up to the container capnp service to hold the monitor inflight if the start is already inflight.

for (auto config: ipamConfig) {
auto subnet = kj::str(config.getSubnet());
auto gateway = kj::str(config.getGateway());
if (subnet.findFirst(':') != kj::none) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: consider checking the findFirst first, then doing to allocation/copy for the subnet and gateway

// we simply return false while avoiding an unnecessary error.
if (response.statusCode == 404) {
co_return InspectResponse{.isRunning = false, .ports = {}};
co_return InspectResponse{.isRunning = false, .ports = {}, .hostsPath = kj::none};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
co_return InspectResponse{.isRunning = false, .ports = {}, .hostsPath = kj::none};
co_return InspectResponse{
.isRunning = false,
.ports = {},
.hostsPath = kj::none,
};

auto hostsPath = getHostsPathFromInspectResponse(response.body);

co_return InspectResponse{
.isRunning = running, .ports = kj::mv(portMappings), .hostsPath = kj::mv(hostsPath)};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
.isRunning = running, .ports = kj::mv(portMappings), .hostsPath = kj::mv(hostsPath)};
.isRunning = running,
.ports = kj::mv(portMappings),
.hostsPath = kj::mv(hostsPath),
};

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