如何使用gracefulStop关闭所有grpc服务器流?

2023-12-08

我试图停止从服务器端连接到流服务器的所有客户端。 其实我正在使用GracefulStop优雅地处理它的方法。

我正在等os.Interrupt在通道上发出信号以执行 gRPC 的正常停止。但它被卡住了server.GracefulStop()当客户端连接时。

func (s *Service) Subscribe(_ *empty.Empty, srv clientapi.ClientApi_SubscribeServer) error {
    ctx := srv.Context()

    updateCh := make(chan *clientapi.Update, 100)
    stopCh := make(chan bool)
    defer func() {
        stopCh<-true
        close(updateCh)
    }

    go func() {
        ticker := time.NewTicker(1 * time.Second)
        defer func() {
            ticker.Stop()
            close(stopCh)
        }
        for {
            select {
            case <-stopCh:
                return
            case <-ticker.C:
                updateCh<- &clientapi.Update{Name: "notification": Payload: "sample notification every 1 second"}
            }
        }
    }()

    for {
        select {
        case <-ctx.Done():
            return ctx.Err()

        case notif := <-updateCh:
            err := srv.Send(notif)
            if err == io.EOF {
                return nil
            }

            if err != nil {
                s.logger.Named("Subscribe").Error("error", zap.Error(err))
                continue
            }
        }
    }
}

我预计context在方法中ctx.Done()可以处理它并打破 for 循环。 如何关闭像这样的所有响应流?


创建一个global context用于您的 gRPC 服务。因此,浏览各个部分:

  • 每个 gRPC 服务请求都将使用此上下文(以及客户端上下文)来满足该请求
  • os.Interrupt处理程序将取消全局上下文;从而取消任何当前正在运行的请求
  • 终于发出了server.GracefulStop()- 应该等待所有活动的 gRPC 调用完成(如果他们没有立即看到取消)

例如,在设置 gRPC 服务时:

pctx := context.Background()
globalCtx, globalCancel := context.WithCancel(pctx)

mysrv := MyService{
    gctx: globalCtx
}

s := grpc.NewServer()
pb.RegisterMyService(s, mysrv)

os.Interrupt处理程序启动并等待关闭:

globalCancel()
server.GracefulStop()

gRPC 方法:

func(s *MyService) SomeRpcMethod(ctx context.Context, req *pb.Request) error {

    // merge client and server contexts into one `mctx`
    // (client context will cancel if client disconnects)
    // (server context will cancel if service Ctrl-C'ed)

    mctx, mcancel := mergeContext(ctx, s.gctx)

    defer mcancel() // so we don't leak, if neither client or server context cancels

    // RPC WORK GOES HERE
    // RPC WORK GOES HERE
    // RPC WORK GOES HERE

    // pass mctx to any blocking calls:
    // - http REST calls
    // - SQL queries etc.
    // - or if running a long loop; status check the context occasionally like so:

    // Example long request (10s)
    for i:=0; i<10*1000; i++ {
        time.Sleep(1*time.Milliscond)

        // poll merged context
        select {
            case <-mctx.Done():
                return fmt.Errorf("request canceled: %s", mctx.Err())
            default:
        }
    }
}

And:

func mergeContext(a, b context.Context) (context.Context, context.CancelFunc) {
    mctx, mcancel := context.WithCancel(a) // will cancel if `a` cancels

    go func() {
        select {
        case <-mctx.Done(): // don't leak go-routine on clean gRPC run
        case <-b.Done():
            mcancel() // b canceled, so cancel mctx 
        }
    }()

    return mctx, mcancel
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用gracefulStop关闭所有grpc服务器流? 的相关文章

  • 在 Go 中解析 RFC-3339 / ISO-8601 日期时间字符串

    我尝试解析日期字符串 2014 09 12T11 45 26 371Z 在围棋中 该时间格式定义为 RFC 3339 日期时间 https datatracker ietf org doc html rfc3339 section 5 6
  • 无法将字符串解组为 int64 类型的 Go 值

    我有结构 type tySurvey struct Id int64 json id omitempty Name string json name omitempty I do json Marshal在 HTML 页面中写入 JSON
  • Google App Engine Golang 没有这样的文件或目录

    我正在用 Go 开发一个 Google App Engine 项目 并陷入了读取文件的困境 事实上 应用程序在本地运行得很好 然而 部署时 它会恐慌告诉我没有这样的文件或目录 这是我的 fileValue 方法 func fileValue
  • 数据库连接最佳实践

    我有一个使用 net http 的应用程序 我使用 http 注册了一些处理程序 这些处理程序需要从数据库中获取一些内容 然后才能继续编写响应并完成请求 我的问题是连接到该数据库的最佳实践是什么 我希望它能够以每分钟 1 个请求或每秒 10
  • Golang、mysql:错误1040:连接过多

    我正在使用 github com go sql driver mysql 驱动程序 我打开一个数据库 db err sql Open mysql str 然后我有两个函数 每个函数被调用 200 次 并使用以下 mysql 代码 rows
  • Bazel 构建缺少严格的依赖关系

    我正在尝试使用 brazel 构建 Go 应用程序 它是一个现有的私有 GitHub 存储库 位置如下 github xyz com repo name 我正在研究 我的目标是从 main go 文件创建一个二进制文件 该文件的方法依赖于其
  • Go API 在 html 中显示 swagger api 规范 (json) (Swagger UI)

    我有一个服务于特定端口的应用程序 gorilla mux 我也有一个 json 文件形式的 swagger API 规范 是否有任何 go API 可以像 spring boot 一样从 JSON 文件生成 swagger UI 定义 我正
  • Golang - 更改 Windows 上的构建工作路径

    我正在使用 SublimeText3 GoSublime 插件 在 Windows 8 上测试简单的 Go 程序 go run v example go 在运行之前它正在内部编译 应用程序数据 本地 温度 目录 我的防病毒程序认为这是病毒并
  • gRPC 客户端重新连接逻辑导致服务器端打开重复流

    我有一个使用两个双向流的 gRPC 客户端 由于目前未知的原因 当我们每小时发送一次 keepAlive ping 时 会出现 onError 并带有statusRuntimeException在两个流上都被调用 为了处理重新连接 我在 j
  • GO并发编程测试

    我试图确保我的并发程序不存在以下情况 僵局 livelock 饥饿 我找到了以下工具http blog golang org race detector http blog golang org race detector 我尝试编译并运行
  • 使用 crypto/ssh 的 golang scp 文件

    我正在尝试通过 ssh 下载远程文件 以下方法在 shell 上运行良好 ssh hostname tar cz opt local folder gt folder tar gz 然而 golang 上的相同方法在输出工件大小方面存在一些
  • 给定方法值,获取接收者对象

    Go 有没有办法从方法值获取接收者对象 例如有没有这样的MagicFunc这将使以下程序输出字符串my info来自底层 Foo 实例 package main import fmt type Foo struct A string fun
  • 视频第一帧

    我正在创建一个单页应用程序 后端使用 Golang 前端使用 javascript 我想找到一种使用 Golang 获取视频第一帧的方法 首先 我将 mp4 视频文件上传到服务器 它保存在服务器上 有没有办法使用 Golang 获取该视频的
  • 如何在C#中执行Go函数

    有没有办法从 C 执行 Go 函数 例如 对于 Python 我会使用 Ironpython 我知道我可以生成一个进程来执行 Go 脚本 但如果可能的话 我真的不想回退到这样的解决方案 Google 搜索没有显示任何内容 那么有什么方法可以
  • Go 无法推断赋值中的类型:“non-name on left side of :=”

    该片段按预期工作play golang org p VuCl OKMav http play golang org p VuCl OKMav i 10 next 11 prev i i next 然而这个几乎相同的片段给出了non name
  • 如何从非英语字符串解析go中的月份

    我想将以下字符串解析为 go 中的日期 This item will be released on March 9 2014 我跟着this https stackoverflow com questions 14106541 go par
  • 微服务架构中protobuf文件的组织

    在我的公司 我们有一个由微服务组织的系统 每个服务都有一个专用的 git 存储库 我们想引入 gRPC 并且想知道如何共享 protobuf 文件并为我们的各种语言构建库 根据我们收集的一些示例 我们最终决定使用一个包含所有 protobu
  • 错误“binary.Write:无效类型”是什么意思?

    下面显示的代码 我创建了一个结构类型并希望将其编码为二进制 但它显示binary Write invalid type main Stu错误 我读过一些类似的代码 但我找不到为什么我的代码不起作用 type Stu struct Name
  • 使用覆盖率信息测试 Go 中的 os.Exit 场景 (coveralls.io/Goveralls)

    这个问题 如何在 Go 中测试 os exit 场景 https stackoverflow com questions 26225513 how to test os exit scenarios in go 以及其中得票最高的答案 列出
  • 编写每个处理程序中间件

    我希望从处理程序中提取一些重复的逻辑 并将其放入一些每个处理程序的中间件中 特别是 CSRF 检查 检查现有会话值 即身份验证或预览页面 等 我读了关于此的几篇文章 http justinas org writing http middle

随机推荐

  • NSTImer 事件会阻塞主线程吗?

    当我们使用 NSTimer 时 一旦在上述时间间隔后调用回调 UI 是否会被阻塞 那要看 大多数时候 这不会成为问题 If 但是 满足以下两个条件 NSTimer will阻塞UI线程 定时器被安排在NSRunLoop主线程的 每当您通过调
  • php:逆转 mysql_real_escape_string 对二进制文件的影响

    我构建了一个网页 用户可以在其中提交 PDF 然后将其插入到 Mediumblob 中的 MySQL 数据库中 以便稍后检索 这一切都工作正常 除非 PDF 包含图像或嵌入字体 在这种情况下图像会损坏并且使用该字体的任何文本都会消失 Acr
  • 检查mysql连接是否有效

    我有一个长时间运行的 php 脚本 它基本上是一个无限循环监听事件 它是一个 xmpp 机器人 我用以下命令启动脚本nohup php bot php 脚本的原始结构就像 mysqli mysqli connect while 1 if e
  • 如何在 C# 中解除套接字绑定?

    我在制作的测试应用程序中重用服务器套接字时遇到一些问题 基本上 我有一个既实现客户端又实现服务器端的程序 我出于测试目的运行该程序的两个实例 一个实例开始托管 另一个实例连接 这是监听代码 private void Listen Click
  • 如何处理 AngularJS 路由找不到资源

    在传统的数据驱动 Web 应用程序中 我们经常尝试根据 URL 中传递的 ID 加载资源 如果资源不存在 我们将返回 404 页面 我们应该如何在 AngularJS 中实现同样的目标 我已经按照 AngularJS 电话目录教程进行操作
  • 设置WKInterfacePicker颜色(文本或轮廓)

    有谁知道如何设置文本颜色或焦点样式轮廓颜色WKInterfacePicker 我没有看到它的界面生成器 我无法在代码中找到任何可以设置它的属性项 这是IB 您无法更改默认选择器的颜色 But you can manipulate the v
  • C 随机数生成(纯 C 代码,无库或函数)

    我需要用 C 语言生成一些随机数来测试和调试系统 该系统是一个定制硬件 SoC 功能有限 因此我只能使用基本的数学运算 不 我不能在 stdlib 或 math h 中使用随机数生成器 我需要自己写 那么有某种算法可以生成随机数吗 我知道一
  • 通过使用 htaccess 替换空格

    你好 我的 htaccess 中有这段代码
  • 通过正则表达式查找句子中的数字

    我需要一个正则表达式来查找句子中的所有数字 例如 我有3根香蕉和37个气球 我会得到 3 37 时间是20 00 我有7辆坦克 我会得到 20 00 7 将字符串拆分为 0 9 JAVA String numbers yourString
  • 如何同时编辑 ASP.NET ListView 控件中的所有行?

    我想知道如何立即将所有 ListView 行置于编辑模式 我并不是在寻找一次编辑每一行的传统行为 答案可以是 C 或 VB NET 另外 如果可能的话 请提供在编辑所有行后保存每行更改的任何示例代码 可能最简单的方法是仅使用 ListVie
  • Smartgwt selectitem键值问题

    我有一个SelectItem我通过一个填充Map具有此组合的列表网格字段内 所以很好 但是当我选择组合框中的任何项目而不是获取地图的描述或值时 会将键放入列表网格字段中 我怎样才能让我设置值而不是键 现在我尝试使用 AddChangeHan
  • 当 python 访问具有 None 值的二维列表时发出警告

    我想创建一个n npython 中的列表 其中大部分元素都用 None 初始化 然后我将在 for 循环中设置一些元素 但在该行中我将对角线元素设置为0 我得到了一个警告突出显示 j 在 PyCharm 中 说 意外类型 整数 整数 可能的
  • 无法在后台的 while 循环中发布异步任务的进度 - Android

    我想从 doInBackground 更新对话框的下载进度 我正在打印日志并发布进度 他们都没有工作 它最后更新对话框并最后一次打印所有日志值 private class DownloadEReport extends AsyncTask
  • 关键字“current_timestamp”附近的语法不正确 - 但仅限于一个数据库

    我有一个 SQL Server 2008 R2 实例 上面有多个数据库 我正在尝试在其中一个数据库 我们称之为 DB1 上运行表值函数 该函数将日期作为输入并返回相关信息表 我这样运行我的查询 SELECT FROM dbo getAllS
  • R 中的显式公式与符号导数

    我想评估某些函数的高阶导数f in R 我有两种可能性 Either I determine a general expression for f k the k th derivative of f which I can do in m
  • 64 位 Windows 上的注册表重定向

    我运行的是 64 位 Windows 并且我想创建注册表项HKCU Software Classes Wow6432Node CLSID myguid InprocServer32使用 C 我应该告诉它写入哪个注册表项 以便将其重定向到上面
  • 如何在 xslt 1.0 中求平方根

    我想在 xslt 文件中进行一些计算 并且需要在公式中进行一些平方根 有人可以指出是否可能以及如何实现吗 感谢磨坊 一个可以使用sqrt的模板 函数FXSL 一 在 XSLT 1 0 中
  • 使用内连接获取oracle中特定列值计数

    我通过加入两个表获得了一些列和值 Select tbl orderdetails category name tbl orderdetails branch name tbl ordermaster created date tbl ord
  • 有什么好的教程或书籍可以帮助您学习使用 PHP 进行信用卡处理? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我正在寻找一本很好的教程或书籍来解释如何通过您网站上的表单处理客户的信用卡 我读过一些有关使用curl 的内容 但这不是完整的教程 我正在寻找一个课
  • 如何使用gracefulStop关闭所有grpc服务器流?

    我试图停止从服务器端连接到流服务器的所有客户端 其实我正在使用GracefulStop优雅地处理它的方法 我正在等os Interrupt在通道上发出信号以执行 gRPC 的正常停止 但它被卡住了server GracefulStop 当客