Skip to content

Commit 9b511ba

Browse files
authored
refactor(sess!): remove legacy APIs and unused helpers (#1847)
Close #1845 The development build already requires sess IPC protocol 2 and is incompatible with past releases. Use this compatibility break to remove the old R API compatibility layer and helpers whose roles have ended. - **`use_httpgd`, `use_jgd`, and their compatibility helpers:** `use_httpgd` was introduced in #1684, and `use_jgd` in #1706. #1817 replaced them with `plot_backend`, retaining the old arguments through `.warn_deprecated_plot_args()` and `.legacy_plot_backend()`. Extension callers already use `plot_backend`; removing the old arguments now also removes the need for these helpers. - **`register_hooks()`:** Introduced in #1684 for standalone hook registration and re-registration. It now delegates to `runtime_start()`, which `connect()` already calls directly, and has no extension callers. Re-registering also resets runtime-owned devices and viewer state without updating reconnect options, so this wrapper no longer provides a coherent independent configuration API. Keep the internal runtime lifecycle and use `connect()` as the public integration entry point. - **`rebind()`:** Introduced in #1684. #1739 migrated all callers to `.runtime_rebind()`, which records bindings for restoration when the runtime stops. Only the unused old definition remained. - **`json_rpc_response()` and `json_rpc_error()`:** Included in [#1684](#1684), but the upstream `sess` branch history shows they served the earlier HTTP `/rpc` implementation. [The WebSocket conversion](41b298a) removed their callers before sess reached main. Delete these unused HTTP response builders; the active `"json_rpc_error"` condition class remains. Update documentation, installer export checks, and test fixtures to match. Backend selection, fallback, and reconnect behavior remain unchanged, and the IPC protocol stays at version 2. Breaking API change: `connect()` no longer accepts `use_httpgd` or `use_jgd`, and `register_hooks()` is no longer exported. Use `plot_backend` and `connect()` instead.
1 parent 5ddebde commit 9b511ba

14 files changed

Lines changed: 49 additions & 261 deletions

File tree

‎R/sess-package-install.R‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ sess_verify_package <- function(library, required, expected_revision, interactiv
1919
"stopifnot(identical(",
2020
"utils::packageDescription('sess',lib.loc=a[1],fields='Config/vscode-R/source-revision'),",
2121
"a[3]));",
22-
"stopifnot(all(c('connect','notify_client','register_hooks','request_client') %in% getNamespaceExports(ns)));",
22+
"stopifnot(all(c('connect','notify_client','request_client') %in% getNamespaceExports(ns)));",
2323
"if (a[4] == 'TRUE') {",
2424
"stopifnot(all(c('interactive_stop','display') %in% getNamespaceExports(ns)));",
2525
"stopifnot(all(vapply(c('interactive_start','interactive_execute'),",

‎R/tests/sess_source.R‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ local({
129129
cli_library <- file.path(project, "library")
130130
dir.create(cli_library, recursive = TRUE)
131131
writeLines(".libPaths(c(file.path(getwd(), \"library\"), .libPaths()))", file.path(project, ".Rprofile"))
132-
exports <- c("connect", "notify_client", "register_hooks", "request_client")
132+
exports <- c("connect", "notify_client", "request_client")
133133
writeLines(paste0(exports, " <- function(...) NULL"), file.path(pkg, "R", "zzz.R"))
134134
writeLines(paste0("export(", exports, ")"), file.path(pkg, "NAMESPACE"))
135135
previous_profile <- Sys.getenv("R_PROFILE_USER", unset = NA_character_)

‎sess/DESCRIPTION‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: sess
22
Type: Package
33
Title: High-Performance IPC Bridge for R Sessions
4-
Version: 3.0.9000.9001
4+
Version: 3.0.9000.9002
55
Authors@R: c(
66
person(given = "Randy",
77
family = "Lai",
@@ -42,6 +42,7 @@ Suggests:
4242
tinytest
4343
NeedsCompilation: no
4444
Config/vscode-R/Interactive: 1
45+
Config/roxygen2/markdown: TRUE
4546
Config/roxygen2/version: 8.1.0
4647
Config/build/bootstrap: TRUE
4748
Config/vscode-R/source-revision: @VSCODE_R_SESS_SOURCE_REVISION@

‎sess/NAMESPACE‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ export(connect)
44
export(display)
55
export(interactive_stop)
66
export(notify_client)
7-
export(register_hooks)
87
export(request_client)

‎sess/R/hooks.R‎

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,8 @@
1-
#' Register VS Code runtime integrations
2-
#'
3-
#' @param use_rstudioapi Logical. Enable rstudioapi emulation.
4-
#' @param use_httpgd Deprecated. Logical. Enable httpgd plot device if available.
5-
#' NULL means unspecified; legacy calls default to TRUE. Use `plot_backend` instead.
6-
#' @param use_jgd Deprecated. Logical. Enable jgd plot device if available.
7-
#' NULL means unspecified; legacy calls default to FALSE. Use `plot_backend` instead.
8-
#' @param plot_backend Plot backend: `auto`, `jgd`, `httpgd`, `standard`, or
9-
#' `native`. NULL also selects `auto`. Deprecated flags select the backend
10-
#' only when this argument is omitted.
11-
#' @export
12-
register_hooks <- function(use_rstudioapi = TRUE, use_httpgd = NULL, use_jgd = NULL,
13-
plot_backend = c("auto", "jgd", "httpgd", "standard", "native")) {
14-
has_httpgd <- !is.null(use_httpgd)
15-
has_jgd <- !is.null(use_jgd)
16-
.warn_deprecated_plot_args(has_httpgd, has_jgd)
17-
backend <- if (missing(plot_backend) && (has_httpgd || has_jgd)) {
18-
.legacy_plot_backend(use_httpgd, use_jgd)
19-
} else {
20-
.resolve_plot_backend(plot_backend)
21-
}
22-
runtime_start(use_rstudioapi, backend)
23-
}
24-
25-
.warn_deprecated_plot_args <- function(has_httpgd, has_jgd) {
26-
old_args <- c(if (has_httpgd) "use_httpgd", if (has_jgd) "use_jgd")
27-
if (length(old_args)) {
28-
warning("[sess] ", paste(old_args, collapse = " and "),
29-
if (length(old_args) == 1L) " is deprecated; use plot_backend instead." else
30-
" are deprecated; use plot_backend instead.", call. = FALSE)
31-
}
32-
invisible(NULL)
33-
}
34-
351
.resolve_plot_backend <- function(plot_backend) {
362
if (is.null(plot_backend)) return("auto")
373
match.arg(plot_backend, c("auto", "jgd", "httpgd", "standard", "native"))
384
}
395

40-
.legacy_plot_backend <- function(use_httpgd, use_jgd) {
41-
if (is.null(use_httpgd) || is.na(use_httpgd)) use_httpgd <- TRUE
42-
if (is.null(use_jgd) || is.na(use_jgd)) use_jgd <- FALSE
43-
if (use_jgd && use_httpgd) "auto" else if (use_jgd) "jgd" else
44-
if (use_httpgd) "httpgd" else "standard"
45-
}
46-
476
.select_plot_backend <- function(plot_backend, has_httpgd, has_jgd) {
487
if (plot_backend == "native") return("native")
498
if (plot_backend %in% c("auto", "jgd") && has_jgd) return("jgd")

‎sess/R/server.R‎

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,8 @@
33
#' @param endpoint Character. Local named pipe / Unix domain socket endpoint.
44
#' If NULL, uses SESS_ENDPOINT, then SESS_DISCOVERY_FILE.
55
#' @param use_rstudioapi Logical. Enable rstudioapi emulation. Defaults to TRUE.
6-
#' @param use_httpgd Deprecated. Logical. Use httpgd for plotting if available.
7-
#' NULL means unspecified; legacy calls default to TRUE. Use `plot_backend` instead.
8-
#' @param use_jgd Deprecated. Logical. Use jgd for plotting if available.
9-
#' NULL means unspecified; legacy calls default to FALSE. Use `plot_backend` instead.
106
#' @param plot_backend Plot backend: `auto`, `jgd`, `httpgd`, `standard`, or
11-
#' `native`. NULL also selects `auto`. Deprecated flags select the backend
12-
#' only when this argument is omitted.
7+
#' `native`. NULL also selects `auto`.
138
#' @details When SESS_DISCOVERY_FILE describes the connected endpoint, an
149
#' unexpected disconnect waits for a replacement endpoint in that file and
1510
#' reconnects with the same runtime options and session identity. The optional
@@ -18,17 +13,9 @@
1813
#' string clears it, and an omitted field leaves it unchanged. Set
1914
#' `options(sess.quiet = TRUE)` to suppress the successful connection message.
2015
#' @export
21-
connect <- function(endpoint = NULL, use_rstudioapi = TRUE, use_httpgd = NULL,
22-
use_jgd = NULL,
16+
connect <- function(endpoint = NULL, use_rstudioapi = TRUE,
2317
plot_backend = c("auto", "jgd", "httpgd", "standard", "native")) {
24-
has_httpgd <- !is.null(use_httpgd)
25-
has_jgd <- !is.null(use_jgd)
26-
.warn_deprecated_plot_args(has_httpgd, has_jgd)
27-
plot_backend <- if (missing(plot_backend) && (has_httpgd || has_jgd)) {
28-
.legacy_plot_backend(use_httpgd, use_jgd)
29-
} else {
30-
.resolve_plot_backend(plot_backend)
31-
}
18+
plot_backend <- .resolve_plot_backend(plot_backend)
3219
# Invalidate poll callbacks and restore a previous runtime before reconnecting.
3320
.transport_disconnect(silent = TRUE)
3421
.sess_env$con <- NULL

‎sess/R/utils.R‎

Lines changed: 0 additions & 48 deletions
This file was deleted.

‎sess/README.md‎

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,13 @@ sess::connect(
6565
)
6666
```
6767

68-
If `plot_backend` is omitted, `sess::connect()` uses `auto`. The VS Code extension
69-
passes its configured backend explicitly. Calls that supply the deprecated
70-
`use_httpgd` or `use_jgd` arguments still use those values when `plot_backend`
71-
is omitted. These deprecated arguments default to `NULL`, meaning unspecified.
72-
When either is non-NULL, the unspecified flag uses its legacy default
73-
(`use_httpgd = TRUE`, `use_jgd = FALSE`). If both are NULL, the backend is `auto`.
68+
If `plot_backend` is omitted or set to `NULL`, `sess::connect()` uses `auto`.
69+
The VS Code extension passes its configured backend explicitly.
70+
71+
For code migrating from earlier `sess` APIs, replace `use_httpgd` and
72+
`use_jgd` with `plot_backend` (for example, `sess::connect(plot_backend = "httpgd")`).
73+
`register_hooks()` has been removed; `connect()` initializes the runtime
74+
integration when it connects.
7475

7576
If `endpoint` is omitted, `connect()` resolves it in this order:
7677

@@ -116,7 +117,7 @@ finding managed terminal discovery files; `sess` does not use it as identity.
116117

117118
## What `sess` changes in your R session
118119

119-
Once connected, `sess` registers hooks (via `register_hooks()`) that redirect
120+
Once connected, `sess` registers runtime integrations that redirect
120121
R's interactive features to the client:
121122

122123
| R feature | Behavior |
@@ -132,8 +133,6 @@ These changes are undone when the connection closes. `sess` removes its task
132133
callbacks, closes its graphics devices, and restores any options, bindings, S3
133134
methods and plot hooks it replaced (unless other code has since changed them).
134135
A plot held only by a jgd device may not survive a disconnect or window reload.
135-
Calling `register_hooks()` again replaces the previous installation rather than
136-
stacking hooks.
137136

138137
### Graphics devices
139138

@@ -152,10 +151,8 @@ For displaying R plots, `sess` chooses a graphics device in this order when
152151
In VS Code, this is controlled by the `r.plot.backend` setting.
153152
`plot_backend = "native"` leaves the existing R graphics device option, plot
154153
hooks, plot task callbacks, and devices untouched. The `standard` backend continues
155-
to use the static plot viewer. When `plot_backend` is omitted, the existing
156-
`use_httpgd`/`use_jgd` arguments keep their previous meanings, but are
157-
deprecated and warn when supplied with non-NULL values, including `FALSE`.
158-
Use `plot_backend` for new code.
154+
to use the static plot viewer. When `plot_backend` is omitted or `NULL`, `auto`
155+
is used.
159156

160157
### Options and environment variables
161158

‎sess/inst/tinytest/test-native-plot.R‎

Lines changed: 18 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
# Explicit backends preserve the old boolean API and keep native distinct from
2-
# the standard static viewer.
1+
# Explicit backends preserve native behavior and keep it distinct from the
2+
# standard static viewer.
33
local({
44
resolve <- sess:::.resolve_plot_backend
5-
legacy <- sess:::.legacy_plot_backend
65
select <- sess:::.select_plot_backend
76
choices <- c("auto", "jgd", "httpgd", "standard", "native")
87
expect_equal(eval(formals(sess::connect)$plot_backend), choices)
9-
expect_equal(eval(formals(sess::register_hooks)$plot_backend), choices)
108
expect_equal(resolve(choices), "auto")
119
expect_equal(resolve(NULL), "auto")
12-
expect_equal(legacy(FALSE, FALSE), "standard")
13-
expect_equal(legacy(TRUE, FALSE), "httpgd")
14-
expect_equal(legacy(FALSE, TRUE), "jgd")
15-
expect_equal(legacy(TRUE, TRUE), "auto")
1610
for (backend in c("auto", "jgd", "httpgd", "standard", "native")) {
1711
expect_equal(resolve(backend), backend)
1812
}
@@ -39,7 +33,7 @@ local({
3933
options(device = original_device)
4034
}, add = TRUE)
4135

42-
sess::register_hooks(use_rstudioapi = FALSE, plot_backend = "native")
36+
sess:::runtime_start(use_rstudioapi = FALSE, plot_backend = "native")
4337
state <- sess:::.runtime_state()
4438
expect_true(isTRUE(state$active))
4539
expect_true(identical(getOption("device"), sentinel_device))
@@ -57,97 +51,23 @@ local({
5751
expect_equal(grDevices::dev.list(), original_devices)
5852
})
5953

60-
# Legacy arguments still work, but public callers are directed to plot_backend.
54+
# Removed arguments are rejected before connect changes transport or runtime state.
6155
local({
62-
old_device <- getOption("device")
63-
sentinel_device <- function(...) stop("R's device option was used")
64-
options(device = sentinel_device)
65-
on.exit({
66-
sess:::runtime_stop()
67-
options(device = old_device)
68-
}, add = TRUE)
69-
70-
warnings <- character()
71-
withCallingHandlers(
72-
sess::register_hooks(use_rstudioapi = FALSE, use_httpgd = TRUE,
73-
use_jgd = TRUE, plot_backend = "native"),
74-
warning = function(w) {
75-
warnings <<- c(warnings, conditionMessage(w))
76-
invokeRestart("muffleWarning")
77-
}
78-
)
79-
expect_length(warnings, 1L)
80-
expect_true(grepl("use_httpgd and use_jgd", warnings[[1L]], fixed = TRUE))
81-
expect_true(grepl("plot_backend", warnings[[1L]], fixed = TRUE))
82-
expect_true(identical(getOption("device"), sentinel_device))
83-
})
84-
85-
local({
86-
# Exercise both public entry points without starting graphics or connecting
87-
# to a server. NULL can also be forwarded by wrappers as an unspecified flag.
88-
cases <- list(
89-
list(args = list(), backend = "auto", deprecated = character()),
90-
list(args = list(use_httpgd = NULL, use_jgd = NULL), backend = "auto",
91-
deprecated = character()),
92-
list(args = list(use_httpgd = TRUE), backend = "httpgd", deprecated = "use_httpgd"),
93-
list(args = list(use_httpgd = FALSE), backend = "standard", deprecated = "use_httpgd"),
94-
list(args = list(use_jgd = TRUE), backend = "auto", deprecated = "use_jgd"),
95-
list(args = list(use_jgd = FALSE), backend = "httpgd", deprecated = "use_jgd"),
96-
list(args = list(use_httpgd = NULL, use_jgd = TRUE), backend = "auto",
97-
deprecated = "use_jgd"),
98-
list(args = list(use_httpgd = FALSE, use_jgd = NULL), backend = "standard",
99-
deprecated = "use_httpgd"),
100-
list(args = list(use_httpgd = FALSE, use_jgd = TRUE), backend = "jgd",
101-
deprecated = c("use_httpgd", "use_jgd")),
102-
list(args = list(use_httpgd = FALSE, use_jgd = FALSE), backend = "standard",
103-
deprecated = c("use_httpgd", "use_jgd")),
104-
list(args = list(use_httpgd = NA, use_jgd = NA), backend = "httpgd",
105-
deprecated = c("use_httpgd", "use_jgd")),
106-
list(args = list(use_httpgd = FALSE, plot_backend = "native"), backend = "native",
107-
deprecated = "use_httpgd"),
108-
list(args = list(use_httpgd = FALSE, plot_backend = NULL), backend = "auto",
109-
deprecated = "use_httpgd")
110-
)
111-
for (entry_point in c("connect", "register_hooks")) {
112-
env <- new.env(parent = asNamespace("sess"))
113-
entry <- getExportedValue("sess", entry_point)
114-
environment(entry) <- env
115-
selected <- NULL
116-
env$.legacy_plot_backend <- function(...) {
117-
selected <<- sess:::.legacy_plot_backend(...)
118-
selected
119-
}
120-
env$.resolve_plot_backend <- function(...) {
121-
selected <<- sess:::.resolve_plot_backend(...)
122-
selected
123-
}
124-
env$runtime_start <- function(use_rstudioapi, plot_backend) {
125-
selected <<- plot_backend
126-
}
127-
env$.resolve_endpoint <- function(...) ""
128-
for (case in cases) {
129-
selected <- NULL
130-
warnings <- character()
131-
withCallingHandlers(
132-
do.call(entry, c(list(use_rstudioapi = FALSE), case$args)),
133-
warning = function(w) {
134-
msg <- conditionMessage(w)
135-
if (entry_point != "connect" ||
136-
msg != "[sess] Connection info not available. Cannot connect to VS Code.") {
137-
warnings <<- c(warnings, msg)
138-
}
139-
invokeRestart("muffleWarning")
140-
}
141-
)
142-
expect_equal(selected, case$backend)
143-
expect_length(warnings, as.integer(length(case$deprecated) > 0L))
144-
if (length(case$deprecated)) {
145-
expect_true(grepl(paste(case$deprecated, collapse = " and "),
146-
warnings[[1L]], fixed = TRUE))
147-
expect_true(grepl("deprecated; use plot_backend", warnings[[1L]], fixed = TRUE))
148-
}
149-
}
56+
env <- new.env(parent = asNamespace("sess"))
57+
entry <- sess::connect
58+
environment(entry) <- env
59+
disconnected <- FALSE
60+
env$.transport_disconnect <- function(...) {
61+
disconnected <<- TRUE
62+
stop("connect reached transport cleanup")
63+
}
64+
for (arg in c("use_httpgd", "use_jgd")) {
65+
failure <- tryCatch(do.call(entry, setNames(list(TRUE), arg)), error = identity)
66+
expect_true(inherits(failure, "error"))
67+
expect_true(grepl("unused argument", conditionMessage(failure), fixed = TRUE))
68+
expect_false(disconnected)
15069
}
70+
expect_false("register_hooks" %in% getNamespaceExports("sess"))
15171
})
15272

15373
# The public connection path stores native for discovery reconnects and still

‎sess/man/connect.Rd‎

Lines changed: 2 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)