lovoo / goka

Goka is a compact yet powerful distributed stream processing library for Apache Kafka written in Go.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Propose: expose processor state

merlor opened this issue · comments

It will be nice to add a method to expose the processor.state field in order to have more fine grained information about processor state.
Examples could be:

func (g *Processor) GetState() *Signal { return g.state }

func (g *Processor) IsInState(state State) bool { return g.state.IsState(state) }

I think this would expose to much internals and give access to processor management.

But we could expose the Signal.state of type State (which is an int)
https://github.com/lovoo/goka/blob/master/signal.go#L21
with the public states integers defined in
https://github.com/lovoo/goka/blob/master/processor.go#L18
This would be similar to how it is done for views:
https://github.com/lovoo/goka/blob/master/view.go#L438

Also note that there is the ProcessorStats that will tell you more about the managed table.
https://github.com/lovoo/goka/blob/master/processor.go#L783

The problem here is: if we don't want to expose the raw Signal (which we don't want to), we'd to have to provide functions that wrap the signal functions, which kind of pollutes the processor interface in my opinion.

So how about we create a readonly-interface for the signal like this?

type RSignal interface {  // please come up with a better name - I couldn't :)
  ObserveStateChange() *StateChangeObserver 
  WaitForState(state State) chan struct{}
  WaitForStateMin(state State) chan struct{} 
  State() State
  IsState(state State) bool
}

That could safely be returned without compromising state's integrity I'd say.

I see and then you could also do something useful with the state.
The returned channels then need to be read-only, I guess @frairon?
Btw. I like RSignal, but do not know if it violates any best practices ;)

@merlor what excactly do you want to achieve with the Signal, except for comparing the State (int)

Just to make sure that we are on the same track @frairon.
You want to create a function which returns the readonly interface?
like this:

func (p *Processor) GetState() RSignal {
	return p.state
}

@ubunatic actually I just need State (int) because I have to understand in which state (ProcStateIdle,ProcStateStarting...) the processor is; in the first example that i made I exposed Signal only because it contains State (int) and, IMHO, it was a really fast and easy solution.

If you are worried about state integrity and want to be as safe as possible also the "second example method"
(func (g *Processor) IsInState(state State) bool { return g.state.IsState(state) })
could be enough to me, but i think that the solution proposed by @frairon could be pretty useful for many users

@jomaresch yep that was what I meant exactly, just forgot to write the getter-function :D.
@ubunatic you're right for the readonly-channels. I mean it's pretty obvious to the caller that the only thing you can do with it is reading until it's closed, but technically it'd be cleaner to define them as readonly, that's true.

But that would also mean that something like internalSignal := proc.GetSignal().(*goka.Signal) is possible. So you can still get the raw signal.

Yes sure, but that's almost always possible. In the end one might also use reflection to call functions not supposed to be called. I mean the interface is there to protect from making mistakes, not to avoid somine hacking their way into messing up the processor. Or did you mean something else?

Ok, i just wanted to know if I understood it correctly 👍🏼

If i have time, i will implement this proposal.