The first Cursor post tried the generative capabilites of the AI model used (Claude Code 4.5). This is a very interesting area where the AI tooling can leverage the code we are creating, speeding this generation. But let’s be honest: most of the time I’m reading code (done or not by me), trying to understand what is doing. An initial description of a method, a library or an agent, can save me several hours. This time I focused on the code analysis capabilities of the AI model, using a specific problem I had.
The OVN agent without eventlet.
The Neutron OVN agent, that I initially implemented and defined the architecture (I’m so proud…), had an issue during the stop event: it was not receiving the SIGTERM signal. This occurred since eventlet was removed from the agent’s code and oslo.service started being called with the “threading” implementation.
This oslo.service “threading” backend implementation, added in this patch, is one of the most important features added in the last years to this library and provides a complete alternative to the eventlet based backend. This patch is a key resource in the eventlet removal process the OpenStack community is achieving.
The first thing I noticed was a new process, the parent one, that was not before the migration to the “threading” implementation; that could be a good starting point and this is the question I did to the AI: “The @ovn_neutron_agent.py uses oslo.services THREADING backend. It creates a neutron.service.Service object and then calls the launch method. That creates several processes and threads. Please describe all of them.”
The output was incredible, to be honest. Cursor (well, the AI model under the agent), described how the OVN agent is spawned and the different threads that are created. This is the summary (yes, it also makes a summary for lazy people!) of the extended output:
Summary Total threads created (typical configuration): * 1 Cotyledon ServiceWrapper thread (main service thread) * 1 OVS IDL monitoring thread * 1 OVN NB IDL monitoring thread * 1 OVN SB IDL monitoring thread * 1 Metadata proxy thread (if metadata extension enabled) Signal handler threads (on-demand, typically 0-1) Total: 5-6 threads in the main process (plus signal handler threads as needed) Note: With the THREADING backend, all work happens in threads within a single process. No separate processes are forked (unlike the eventlet backend which could use processes). The cotyledon.ServiceManager manages the service lifecycle but runs everything in threads when using the threading backend.
The corrections to the AI answer.
The reply was extensive and detailed, but if failed in the main question I was trying to find: if the new oslo.service “threading” backend implementation was creating additional processes, apart from the one running the agent. The new question to the AI agent, within the same context of the first question (it is very important to keep the same context!) was: “About ServiceManager, it does create a new process to execute the instance of ServiceWrapper. Please, confirm that because you stated that ‘The entire agent runs in one process'”. That was the output:
Summary of corrections: * Process architecture: Clarified that there are two processes: ** Main Process: Entry point that calls service.launch() and blocks in launcher.wait() ** Worker Process: Created by cotyledon.ServiceManager.run() to execute the ServiceWrapper * ServiceWrapper: Changed from ``thread`` to ``process``; — it runs in a separate process created by cotyledon, not a thread in the main process. * Thread counts: Updated to reflect that all threads run within the worker process, not the main process. * Important notes: Added clarification that: ** The THREADING backend uses Python's threading module within processes ** It does not avoid process creation ** cotyledon.ServiceManager.run() creates a worker process The THREADING backend refers to using standard Python threads within processes, not avoiding process creation. The process model (main process + worker process) is similar to the eventlet backend; the difference is the threading model within those processes.
After that and digging more into the new ServiceManager implementation, I found out how to the OS signals were handled. All these debugging steps were always based on questions directly replied by the AI agent while manually checking the code. The AI agent is very useful and speeds up the code analysis, but it always require you to apply your own criteria and knowledge.
Let’s expand a bit more the analysis: OVN agent vs DHCP agent.
Just out of curiosity, before closing the current context I had, I tried something else: to document the differences between the Neutron DHCP agent and the Neutron OVN agent. Both agents, if you know a bit about them, are completely different. The DHCP one is waiting for RPC updates coming from the Neutron API and the agent runs in a continious loop; the OVN agent uses the OVN database updates and is event driven.
The output to the question “describe the differences between the OVN agent and the DHCP agent” was impresive in size and detail. Also for lazy people there was a table summarizing the comparison between both, that is remarkable:
| Aspect | OVN Agent | DHCP Agent | |-----------------------|--------------|-------------------------| | Threads | 4-5 | 39-40 | | Processes | 2 | 2 | | Communication | OVSDB IDL | RPC + Direct calls | | Architecture | Event-driven | Queue-driven | | Extensibility | High (extensions) | Low (monolithic) | | Resource Usage | Low | High | | Complexity | Low-Medium | High | | State Management | OVN databases| Local cache | | Child Processes | Minimal | Many (dnsmasq, proxies) |
And that’s all for today. Before closing the computer, I’m going to ask Claude Code if it can suggest me a good movie for tonight.