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

获取事件处理函数指针地址问题 #22

Open
hexxv opened this issue Jul 17, 2024 · 1 comment
Open

获取事件处理函数指针地址问题 #22

hexxv opened this issue Jul 17, 2024 · 1 comment

Comments

@hexxv
Copy link

hexxv commented Jul 17, 2024

我目前使用的V1版本,代码如下:

// eventbus\nats\consumer.go
func (c *consumer) addHandler(handler eventbus.EventHandler) int {

	pointer := reflect.ValueOf(handler).Pointer()

	c.rw.Lock()
	defer c.rw.Unlock()

	c.handlers[pointer] = handler

	return len(c.handlers)
}

经调试发现:

// eventbus\nats\consumer.go

pointer := reflect.ValueOf(handler).Pointer() // pointer总是返回同一个值

问题:

pointer总是返回同一个值
这将导致:同一个 topic,注册两个处理函数,后注册的会顶掉先注册的。

于是,我在V2发现了这个变动, 代码如下:

// 添加处理器
func (c *consumer) addHandler(handler eventbus.EventHandler) int {
	pointer := reflect.ValueOf(handler).Pointer()

	c.rw.Lock()
	defer c.rw.Unlock()

	if _, ok := c.handlers[pointer]; !ok {
		c.handlers[pointer] = make([]eventbus.EventHandler, 0, 1)
	}

	c.handlers[pointer] = append(c.handlers[pointer], handler)

	return len(c.handlers[pointer])
}

疑问点:

  1. 取pointer的目的? 看上去,V1版本是保证同一个处理函数无论注册多少次只调用一次, V2版本变更为 同一个处理函数注册n次调用n次。
  2. 个人愚见:v2版本看上去像是作者发现v1版本的问题后采用了变更设计的解决方案(我今天使用v1版本刚好遇到了这个问题),如果仅仅是解决V1版本的问题,好像修改一下就可以了:
// eventbus\nats\consumer.go
func (c *consumer) addHandler(handler eventbus.EventHandler) int {

	// pointer := reflect.ValueOf(handler).Pointer()
        pointer := reflect.ValueOf(unsafe.Pointer(&handler)).Pointer()

	c.rw.Lock()
	defer c.rw.Unlock()

	c.handlers[pointer] = handler

	return len(c.handlers)
}
@dobyte
Copy link
Owner

dobyte commented Jul 17, 2024

感谢你提出的问题和解决方案。v2版本的初衷确实是为了一个事件同时被多个订阅函数进行处理。当时还考虑到取消订阅的API,因而采用了slice的的方案来存入多个函数。但目前的取消订阅的API会出现一个取消全部都取消的问题,因此后续会对该API进行优化,到时候会采用你的方案来进行处理。

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

No branches or pull requests

2 participants