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

feat: close #7

Merged
merged 1 commit into from
Feb 7, 2017
Merged

feat: close #7

merged 1 commit into from
Feb 7, 2017

Conversation

shaoshuai0102
Copy link
Contributor

@shaoshuai0102 shaoshuai0102 commented Jan 26, 2017

Checklist
  • npm test passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)
Description of change

lib/leader.js Outdated
close() {
this.removeAllListeners();
this._server.removeAllListeners();
this._server.close();
Copy link
Member

Choose a reason for hiding this comment

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

Server close,follower 也会优雅断开么?

@popomore
Copy link
Member

那最后调用 client 的 close 就好了么。

如果多个 client,其中一个 client close 了,对应的 server 会关闭么

@fengmk2
Copy link
Member

fengmk2 commented Feb 3, 2017

close 应该要支持同步和异步方式,例如有些 close 是需要去删除文件的,那么同步 close 实现不了。

@popomore
Copy link
Member

popomore commented Feb 3, 2017

默认用 promise 好了

@gxcsoccer
Copy link
Member

close(callback) 吧

@gxcsoccer
Copy link
Member

那最后调用 client 的 close 就好了么。
如果多个 client,其中一个 client close 了,对应的 server 会关闭么

各管各吧

@popomore
Copy link
Member

popomore commented Feb 3, 2017

server 就一个端口,怎么各管各的?

@shaoshuai0102 shaoshuai0102 changed the title feat: close [WIP] feat: close Feb 3, 2017
@gxcsoccer
Copy link
Member

server 就一个端口,怎么各管各的?

如果是多个 client,要关闭所有的,不然剩下的会继续抢占端口。

当然也可以设计一个协议是专门关闭所有 client 的

@popomore
Copy link
Member

popomore commented Feb 3, 2017

每个 client 的 leader/follower 应该都是通过同一个 server 的端口来通讯的,那这个端口应该什么时候关闭呢?

@shaoshuai0102
Copy link
Contributor Author

shaoshuai0102 commented Feb 3, 2017

这个地方做起来是比较麻烦的,比较完美的办法是,server close 的时候只是从 typeSet 中移除记录,然后再遍历 typeSet + serverMap,如果发现 typeSet 中对于某个 port 来说找不到 serverMap 中对应监听的了就真正关闭 port。否则在多个应用一起跑的用例里面因为 close 可能会互相影响。

宗羽这块比较绕,我的思路对不

@shaoshuai0102 shaoshuai0102 force-pushed the feat-close branch 6 times, most recently from f224193 to f4cf083 Compare February 3, 2017 14:08
@codecov-io
Copy link

codecov-io commented Feb 3, 2017

Codecov Report

Merging #7 into master will increase coverage by 0.31%.

@@            Coverage Diff             @@
##           master       #7      +/-   ##
==========================================
+ Coverage    96.2%   96.51%   +0.31%     
==========================================
  Files          15       15              
  Lines         658      718      +60     
==========================================
+ Hits          633      693      +60     
  Misses         25       25
Impacted Files Coverage Δ
lib/symbol.js 100% <100%> (ø)
lib/client.js 98.8% <100%> (+0.16%)
lib/index.js 97.46% <100%> (+0.09%)
lib/connection.js 93.05% <100%> (-2.47%)
lib/server.js 97.56% <100%> (+2.96%)
lib/utils.js 93.93% <100%> (+2.63%)
lib/leader.js 94.61% <96.15%> (-0.03%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 503410d...2ad1ec4. Read the comment docs.

@popomore
Copy link
Member

popomore commented Feb 3, 2017

有点搞混,这个 port 是 client 对外的 port,还是 leader/follower 通讯的 port

@shaoshuai0102
Copy link
Contributor Author

@popomore 我上面那个回复不对,理解错了。

现在知道怎么做了。当 leader close 的时候,需要:

  • 不再监听实际的 net.Server
  • 解除 cluster name + port 对 net.Server 的独占,允许后面的同 name + port 可以绑定。真正的 net.Server close 暂时可以不做,没有真正的影响。

@popomore
Copy link
Member

popomore commented Feb 3, 2017

为啥不影响,因为就一个单例?

@shaoshuai0102
Copy link
Contributor Author

是的,全局有一个 map,对应 port <=> net.Server instance,关不关 server instance 没有实际影响,是因为影响抢占的是另外一个 cluster client name + port 这个组合,只要解除了这个就哦了。

@fengmk2
Copy link
Member

fengmk2 commented Feb 6, 2017

// close server if no one is listening on this port any more
if (!listening) {
const server = serverMap.get(port);
yield server && server.close();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gxcsoccer 这里做了最后的 close。如果没有 leader 在 listening port 的时候,做最后的关闭。这样就相互不打扰。

@gxcsoccer
Copy link
Member

@shaoshuai0102 windows 下抛错了 https://ci.appveyor.com/project/gxcsoccer/cluster-client/build/1.0.105/job/ermy2q6shh7ivl77

这个就是 close 的时候还没有 init 导致的

@shaoshuai0102
Copy link
Contributor Author

这个好奇怪,在 win 下 同样在 co 里时序好像不能保证

@shaoshuai0102
Copy link
Contributor Author

shaoshuai0102 commented Feb 6, 2017

同步讨论结果:

  • 增加 cluster.close(client) API,这样可以取消对 original client close 方法做 delegate 的限制
  • 基于 客户端对等 的原则,使用上应该不区分 leader 和 follower,调整成 leader.close 不会主动通知 follower close,会等待 follower.close 完成。

@popomore
Copy link
Member

popomore commented Feb 6, 2017

增加 cluster.close(client) API,这样可以取消对 original client close 方法做 delegate 的限制

cluster.close 是哪个对象?单例?

@shaoshuai0102
Copy link
Contributor Author

单例

const cluster = require('cluster-client');

const client = cluster().create();
cluster.close(client);

@popomore
Copy link
Member

popomore commented Feb 6, 2017

leader.close 不会主动通知 follower close,会等待 follower.close 完成。

这句不是很懂,不通知咋等待?

leader 是对外的通道,如果 leader 关了,follow 还有存在的必要?

@popomore
Copy link
Member

popomore commented Feb 6, 2017

这个好像和 client.close 没本质区别?在 client.close 里也可以有相同实现。

@shaoshuai0102
Copy link
Contributor Author

leader 是对外的通道,如果 leader 关了,follow 还有存在的必要?

没有存在的必要。

  1. follower.close() => 直接关闭
  2. leader.close() => mark 为 closing,等连在 leader 上的所有 follower 都 close 了,真正关闭。如果 follower 一直不关是会导致 leader 一直等待不会关。在 egg 的情况不会存在,因为 egg 中 follower 在 app worker 中会比 agent 进程中的 leader 先关闭。之所以这么设计,是考虑 cluster-client 这个模块本身的理念,所有 client 是对等的,不能因为 close 了其中一个 client 导致其他 client 有异常。

这个机制和原生的 net.Server#close 是比较相似的

@shaoshuai0102
Copy link
Contributor Author

这个好像和 client.close 没本质区别?在 client.close 里也可以有相同实现。

内部实现是一样的。但是如果 close 方法挂载到 client 上,会导致如果 real client 上有 generator close 方法时,不能 delegate 到 client 上,这里就有潜规则了。如果用 cluster.close 就规避了这个问题。

@popomore
Copy link
Member

popomore commented Feb 6, 2017

@shaoshuai0102 好的,说的比较清楚了。可以在 egg cluster 模式下测下 close

@shaoshuai0102
Copy link
Contributor Author

改好了 @gxcsoccer

@shaoshuai0102
Copy link
Contributor Author

合并?

@gxcsoccer
Copy link
Member

@shaoshuai0102 再看一遍

@shaoshuai0102
Copy link
Contributor Author

好 egg 1.0 在等这个

@gxcsoccer
Copy link
Member

lgtm

Copy link
Member

@gxcsoccer gxcsoccer left a comment

Choose a reason for hiding this comment

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

+1

lib/leader.js Outdated
});
}

setTimeout(reject, 30000);
Copy link
Member

Choose a reason for hiding this comment

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

reject 应该有一个 err 吧?

@shaoshuai0102
Copy link
Contributor Author

ci 过了

合并发布后 eggjs/egg#310 就可以过了

@gxcsoccer gxcsoccer merged commit 00e6f2f into master Feb 7, 2017
@gxcsoccer
Copy link
Member

+ cluster-client@1.1.0

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.

None yet

5 participants