get_procs() @return docs don't match returned columns, and pid column is the row index

未关闭 适合新手
#532 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

@jmwoliver 已经在做这个了。

开始于 2026年11月6日。

  • #533 来自 @jmwoliver —— 未关闭

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
67/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
r

调研方向

从 R/get.R 开始,追踪 get_procs() 在解析前如何转换 procs() 返回的列表;复现结果显示了实际的 pid 在哪里丢失。然后检查 tests/integrated/test-get.R,并将其中的列断言更新为 snake_case。返回的列与 @return 文档一致、服务器 PID 得以保留,并且 start_time 和 heartbeat 被解析为日期时,即表示完成。

由索引模型根据 Issue 内容生成。

描述

Summary

get_procs() has two related problems. The @return docs don't match the columns it returns, and the pid column holds the row index instead of the real process ID.

Found while reviewing #530 (review comment).

1. @return docs don't match the returned columns

get_procs() (R/get.R) documents these columns: pid, appId, appGuid, appName, appUrl, appRunAs, type, cpuCurrent, cpuTotal, ram.

GET __api__/metrics/procs returns a JSON array of detailedProcInfo objects. In current Connect (src/connect/api/metrics/metrics.go), those objects have these fields:

Field Notes
app_id Int64 serialized as string
app_guid
app_name
app_url
app_run_as
type
cpu_current nullable
ram nullable (bytes)
hostname
job_key
image
start_time
heartbeat nullable
pid "only matters in local"

parse_connectapi_typed() keeps column names as they are, so:

  • The docs use camelCase (appId, cpuCurrent, ...), but the returned columns are snake_case (app_id, cpu_current, ...).
  • cpuTotal is documented, but the server doesn't send it.
  • hostname, job_key, image, start_time, and heartbeat are returned but not documented.

The integration test in tests/integrated/test-get.R checks for appId and appGuid. It only does that when rows come back, which almost never happens on a fresh test server, so the mismatch goes unnoticed.

Smaller point: start_time and heartbeat come back as character, not POSIXct, because get_procs() passes no datetime_cols.

2. pid is the row index, not the process ID

procs() calls GET with the default simplify = FALSE, so the response is an unnamed list of objects. Each object already has a pid. get_procs() then does this:

purrr::imap(raw_proc_data, function(x, y) c(list(pid = y), x))

That code expects a map keyed by PID. With an unnamed list, y is the position (1, 2, ...), so every row gets two pid entries. parse_connectapi() collects columns with unique(names) plus .subset2(), and .subset2() returns the first match. The result has a single pid column holding the index, and the server's real PID is silently dropped.

Reproduction

I built a stub Connect subclass whose procs() returns the server's array shape, parsed the same way Connect$request() does, and ran it through the real get_procs():

devtools::load_all()
json <- '[{"app_id":"12","app_guid":"aaaa-1111","app_name":"shiny-a","app_url":"http://c/a/","app_run_as":"rstudio-connect","type":"shiny","cpu_current":0.05,"ram":104857600,"hostname":"node-1","job_key":"jk1","image":"","start_time":"2026-11-06T10:00:00Z","heartbeat":"2026-11-06T10:05:00Z","pid":4321},
 {"app_id":"34","app_guid":"bbbb-2222","app_name":"api-b","app_url":"http://c/b/","app_run_as":"rstudio-connect","type":"api","cpu_current":null,"ram":null,"hostname":"node-2","job_key":"jk2","image":"ghcr.io/x:1","start_time":"2026-11-06T10:01:00Z","heartbeat":null,"pid":0}]'
Stub <- R6::R6Class("Stub", inherit = Connect, public = list(
  initialize = function() {},
  procs = function() jsonlite::fromJSON(json, simplifyVector = FALSE, simplifyDataFrame = FALSE)
))
out <- get_procs(Stub$new())
out[, c("pid", "app_id", "app_name", "hostname", "start_time", "heartbeat")]

Output:

# A tibble: 2 × 6
    pid app_id app_name hostname start_time           heartbeat
  <int> <chr>  <chr>    <chr>    <chr>                <chr>
1     1 12     shiny-a  node-1   2026-11-06T10:00:00Z 2026-11-06T10:05:00Z
2     2 34     api-b    node-2   2026-11-06T10:01:00Z <NA>

The server sent PIDs 4321 and 0, but pid is 1, 2.

All the returned columns are: pid, app_id, app_guid, app_name, app_url, app_run_as, type, cpu_current, ram, hostname, job_key, image, start_time, heartbeat.

Possible fix

  • Drop the imap() step and pass raw_proc_data straight to parse_connectapi_typed(), with datetime_cols = c("start_time", "heartbeat").
  • Update the @return list to match the fields above.
  • Make the integration test check snake_case names.

Related

#531 (adding get_processes() on GET /v1/system/processes and deprecating get_procs()) is underway. It may fix this as part of the fallback path to __api__/metrics/procs on older servers. If get_procs() stays around in any form, it needs these fixes.

主要语言
R
星标
54
派生
27
PR 合并指标
30 天内没有已合并 PR

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

posit-dev/connectapi 的其他 Issue

查看 posit-dev/connectapi 的全部 Issue

相似的 Issue

更多 R Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。