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

Ability to grab all PIDs in the registry #149

Open
stevohuncho opened this issue Jan 14, 2024 · 9 comments
Open

Ability to grab all PIDs in the registry #149

stevohuncho opened this issue Jan 14, 2024 · 9 comments
Labels

Comments

@stevohuncho
Copy link

It would make things less complicated in my repos if I was able to have a couple more public functions for reading the registry. Right now only being able to get active PID info only by inputing the specific ID I'm looking for isn't too helpful for my case. I require the ability to check what the active PIDs are upon request. Using the event stream to monitor this just bloats my code by needing to create my own mapping to just replicate the privated one. I understand it is privated for mutex reasons, but if these functions could be added it would be very helpful. I have used these functions in my own code before using my fork with no issues, but I think this could be useful to others as well.

registry.go

...

func (r *Registry) GetIDs() []string {
	r.mu.RLock()
	defer r.mu.RUnlock()
	keys := make([]string, 0, len(r.lookup))
	for k := range r.lookup {
		keys = append(keys, k)
	}
	return keys
}

func (r *Registry) GetPIDs() []*PID {
	r.mu.RLock()
	defer r.mu.RUnlock()
	keys := make([]*PID, 0, len(r.lookup))
	for _, v := range r.lookup {
		keys = append(keys, v.PID())
	}
	return keys
}

...
@anthdm
Copy link
Owner

anthdm commented Jan 14, 2024

Makes sense. Let me think about this today and come up with some stuff for you.

@webfrank
Copy link

It would be a very useful addition, also a Lookup function to search for an ID

@chadleeshaw
Copy link

This would be awesome... I wanted to see how balanced the cluster had distributed the activations and could have used this implementation. In my case its probably possible to view this through Prometheus metrics or by writing a subscriber that would essentially mimic the registry. That said, this proposal is easier.

@stevohuncho
Copy link
Author

I stopped using this repo a while ago, but I recommend this Golang actor library it has had all the support I've needed.
https://github.com/asynkron/protoactor-go

@raulriverarojas
Copy link

Hi, idk if anyone has tried to implement this but it seems pretty straightforward and will add good func imo.
My thinking:

I propose adding three new public methods to the Registry that would provide different ways to access PID information:

// GetAllPIDs returns a slice of all currently registered PIDs
func (r *Registry) GetAllPIDs() []*actor.PID {
// Lock for reading
// Create slice with capacity = len(lookup)
// Iterate lookup and collect PIDs
// Return slice
}

// GetPIDsByKind returns all PIDs that match the given kind
func (r *Registry) GetPIDsByKind(kind string) []*actor.PID {
// Lock for reading
// Create slice
// Filter lookup by kind prefix
// Return matching PIDs
}

// GetPIDMap returns a map of actor IDs to their PIDs
func (r *Registry) GetPIDMap() map[string]*actor.PID {
// Lock for reading
// Create map with capacity = len(lookup)
// Copy ID->PID mappings
// Return map
}

Just a couple of questions. I was just wondering what to return from these methods. I don't think returning pointers is safe. Maybe cloning the actors before returning them or just returning PIDs? idk lmk which one I should implement.
Also when running the tests with "make tests" fails. So idk if its just my machine or the tests are not passing right now. I want to make tests for these functions so I wanted to get the rest in a running state for that. Anyways, lmk thanks.

@raulriverarojas
Copy link

@anthdm

@anthdm
Copy link
Owner

anthdm commented Feb 17, 2025

The thing is that retrieving PIDS from the engine is actually an anti-pattern. This is the reason why I kept this on the side for a very long time.

I have made very performant and complicated applications and never have the "thought" of needing the engine to query actors. I would love to see some concrete examples and use-cases that are NOT cluster related. Cause when working with actors over the cluster that's a whole other story.

@raulriverarojas
Copy link

Fair enough. If retrieval using the registry is not wanted behavior that is okay.

Cause when working with actors over the cluster that's a whole other story.

I see, the project only wants to retrieve members info and PIDS through the cluster?

@koola
Copy link

koola commented Feb 20, 2025

The thing is that retrieving PIDS from the engine is actually an anti-pattern. This is the reason why I kept this on the side for a very long time.

I have made very performant and complicated applications and never have the "thought" of needing the engine to query actors. I would love to see some concrete examples and use-cases that are NOT cluster related. Cause when working with actors over the cluster that's a whole other story.

Internally it's useful for example:

func (e *Engine) Shutdown(graceful bool) {
	for _, pid := range e.Registry.GetAllPIDs() {
		<-e.sendPoisonPill(e.Context, graceful, pid).Done()
	}
	if e.remote != nil {
		e.remote.Stop().Wait()
	}
	e.eventStream = nil
	<-e.Stop(e.Registry.GetPID("engine", "router")).Done()
	<-e.Stop(e.Registry.GetPID("engine", "eventstream")).Done()
	slog.Debug("engine shutdown", "pid", e.pid)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants