mirror of
https://github.com/element-hq/synapse.git
synced 2026-08-22 18:50:18 +00:00
Match HomeServer wrapper method names to Python; make RustRuntime clonable
Rename the HomeServer wrapper accessors to mirror the Python methods they call (get_rust_runtime, get_clock), so the wrapper reads 1:1 against synapse/server.py. Make RustRuntime itself a cheaply-clonable handle (Clone + Deref to RustRuntimeInner) rather than exposing Arc<RustRuntimeInner> in signatures. With pyo3's opt-in from_py_object extraction, the same class serves as both the Python-facing object and the Rust-side handle: consumers now declare `runtime: RustRuntime` in their constructors and pyo3 clones it out (an Arc refcount bump), so no separate Py-wrapper type is needed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HyuiV3m44ZbK9o24EnMMES
This commit is contained in:
co-authored by
Claude Opus 5
parent
efb0e1cce4
commit
a6557c7989
@@ -26,7 +26,7 @@ use pyo3::{
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
use crate::reactor::Reactor;
|
||||
use crate::runtime::RustRuntimeInner;
|
||||
use crate::runtime::RustRuntime;
|
||||
|
||||
create_exception!(
|
||||
synapse.synapse_rust.http_client,
|
||||
@@ -75,7 +75,7 @@ fn logging_context_module(py: Python<'_>) -> PyResult<&Bound<'_, PyAny>> {
|
||||
/// Does not handle deferred cancellation or contextvars.
|
||||
pub fn create_deferred<'py, F, O>(
|
||||
py: Python<'py>,
|
||||
runtime: &Arc<RustRuntimeInner>,
|
||||
runtime: &RustRuntime,
|
||||
fut: F,
|
||||
) -> PyResult<Bound<'py, PyAny>>
|
||||
where
|
||||
@@ -91,7 +91,7 @@ where
|
||||
|
||||
// Keep the runtime state (and, through it, the reactor) alive while the
|
||||
// task is in flight.
|
||||
let runtime = Arc::clone(runtime);
|
||||
let runtime = runtime.clone();
|
||||
handle.spawn(async move {
|
||||
let res = task.await;
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ impl RustHandlers {
|
||||
|
||||
// The per-homeserver Rust state, which gives us the tokio runtime
|
||||
// and the Twisted reactor.
|
||||
let runtime = homeserver.rust_runtime(py)?;
|
||||
let runtime = homeserver.get_rust_runtime(py)?;
|
||||
|
||||
let db_pool = PythonDatabasePoolWrapper::new(
|
||||
&homeserver.main_database_pool(py)?,
|
||||
@@ -62,7 +62,7 @@ impl RustHandlers {
|
||||
versions::VersionsHandler {
|
||||
global_unstable_feature_map: Arc::clone(&global_unstable_feature_map),
|
||||
store: Arc::clone(&store),
|
||||
runtime: Arc::clone(&runtime),
|
||||
runtime: runtime.clone(),
|
||||
},
|
||||
)?;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use serde::Serialize;
|
||||
|
||||
use crate::config::{types::RoomCreationPreset, SynapseHomeServerConfig};
|
||||
use crate::deferred::create_deferred;
|
||||
use crate::runtime::RustRuntimeInner;
|
||||
use crate::runtime::RustRuntime;
|
||||
use crate::storage::store::{PerUserExperimentalFeature, Store};
|
||||
|
||||
/// `GET /_matrix/client/versions` response
|
||||
@@ -48,7 +48,7 @@ pub struct VersionsHandler {
|
||||
pub store: Arc<Store>,
|
||||
/// The per-homeserver Rust state, used to bridge our `async` response
|
||||
/// back into a Twisted deferred that Python can `await`.
|
||||
pub runtime: Arc<RustRuntimeInner>,
|
||||
pub runtime: RustRuntime,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
|
||||
@@ -15,12 +15,10 @@
|
||||
|
||||
//! A typed wrapper around the Python `HomeServer`.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use pyo3::{intern, prelude::*};
|
||||
|
||||
use crate::config::SynapseHomeServerConfig;
|
||||
use crate::runtime::{RustRuntime, RustRuntimeInner};
|
||||
use crate::runtime::RustRuntime;
|
||||
|
||||
/// The Python `HomeServer`, as seen from Rust.
|
||||
///
|
||||
@@ -41,14 +39,12 @@ impl<'a, 'py> FromPyObject<'a, 'py> for HomeServer {
|
||||
impl HomeServer {
|
||||
/// The per-homeserver Rust state (`hs.get_rust_runtime()`), which gives
|
||||
/// access to the tokio runtime and the reactor.
|
||||
pub fn rust_runtime(&self, py: Python<'_>) -> PyResult<Arc<RustRuntimeInner>> {
|
||||
let runtime: Bound<'_, RustRuntime> = self
|
||||
pub fn get_rust_runtime(&self, py: Python<'_>) -> PyResult<RustRuntime> {
|
||||
Ok(self
|
||||
.0
|
||||
.bind(py)
|
||||
.call_method0(intern!(py, "get_rust_runtime"))?
|
||||
.extract()?;
|
||||
|
||||
Ok(Arc::clone(runtime.get().inner()))
|
||||
.extract()?)
|
||||
}
|
||||
|
||||
/// The Rust-side view of `hs.config`.
|
||||
@@ -58,7 +54,7 @@ impl HomeServer {
|
||||
|
||||
/// The Synapse `Clock` (`hs.get_clock()`).
|
||||
// TODO: give the clock a typed wrapper of its own.
|
||||
pub fn clock(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
|
||||
pub fn get_clock(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
|
||||
Ok(self
|
||||
.0
|
||||
.bind(py)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
*/
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Context;
|
||||
use http_body_util::BodyExt;
|
||||
@@ -22,7 +21,7 @@ use reqwest::RequestBuilder;
|
||||
|
||||
use crate::deferred::create_deferred;
|
||||
use crate::errors::HttpResponseException;
|
||||
use crate::runtime::{RustRuntime, RustRuntimeInner};
|
||||
use crate::runtime::RustRuntime;
|
||||
|
||||
/// Called when registering modules with python.
|
||||
pub fn register_module(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
@@ -43,7 +42,7 @@ pub fn register_module(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()>
|
||||
#[pyclass]
|
||||
struct HttpClient {
|
||||
client: reqwest::Client,
|
||||
runtime: Arc<RustRuntimeInner>,
|
||||
runtime: RustRuntime,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
@@ -51,7 +50,7 @@ impl HttpClient {
|
||||
#[new]
|
||||
#[pyo3(signature = (runtime, user_agent, http2_only = false))]
|
||||
pub fn py_new(
|
||||
runtime: &Bound<'_, RustRuntime>,
|
||||
runtime: RustRuntime,
|
||||
user_agent: &str,
|
||||
http2_only: bool,
|
||||
) -> PyResult<HttpClient> {
|
||||
@@ -65,10 +64,7 @@ impl HttpClient {
|
||||
|
||||
let client = builder.build().context("building reqwest client")?;
|
||||
|
||||
Ok(HttpClient {
|
||||
client,
|
||||
runtime: Arc::clone(runtime.get().inner()),
|
||||
})
|
||||
Ok(HttpClient { client, runtime })
|
||||
}
|
||||
|
||||
pub fn get<'a>(
|
||||
|
||||
@@ -99,7 +99,7 @@ impl MSC4388RendezvousHandler {
|
||||
eviction_interval: u64,
|
||||
ttl: u64,
|
||||
) -> PyResult<Py<Self>> {
|
||||
let clock = homeserver.clock(py)?;
|
||||
let clock = homeserver.get_clock(py)?;
|
||||
|
||||
// Construct a Python object so that we can get a reference to the
|
||||
// evict method and schedule it to run.
|
||||
|
||||
@@ -123,7 +123,7 @@ impl RendezvousHandler {
|
||||
let base = Uri::try_from(format!("{base}_synapse/client/rendezvous"))
|
||||
.map_err(|_| PyValueError::new_err("Invalid base URI"))?;
|
||||
|
||||
let clock = homeserver.clock(py)?;
|
||||
let clock = homeserver.get_clock(py)?;
|
||||
|
||||
let eviction_duration = SynapseDuration::from_milliseconds(eviction_interval);
|
||||
|
||||
|
||||
+14
-7
@@ -22,6 +22,7 @@
|
||||
//! [`Arc<RustRuntimeInner>`] at construction time and don't need the GIL (or
|
||||
//! the Python-facing object) to reach it afterwards.
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, Mutex, Weak};
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -119,18 +120,24 @@ impl Drop for RustRuntimeInner {
|
||||
}
|
||||
}
|
||||
|
||||
/// The Python-facing handle to the per-homeserver Rust state.
|
||||
/// A cheaply-clonable handle to the per-homeserver Rust state, and the
|
||||
/// Python-facing class for it.
|
||||
///
|
||||
/// Constructed by `HomeServer.get_rust_runtime()`, and passed to the Rust
|
||||
/// classes that need it (which take a clone of the inner [`Arc`] and drop
|
||||
/// this handle).
|
||||
#[pyclass(frozen, name = "RustRuntime", module = "synapse.synapse_rust")]
|
||||
/// One instance is constructed per homeserver by
|
||||
/// `HomeServer.get_rust_runtime()`. Rust classes that need it take it as a
|
||||
/// constructor argument — pyo3 extracts a `#[pyclass]` that is `Clone` by
|
||||
/// cloning, which here is just an `Arc` refcount bump — and hold their own
|
||||
/// clone. Derefs to [`RustRuntimeInner`].
|
||||
#[pyclass(frozen, from_py_object, module = "synapse.synapse_rust")]
|
||||
#[derive(Clone)]
|
||||
pub struct RustRuntime {
|
||||
inner: Arc<RustRuntimeInner>,
|
||||
}
|
||||
|
||||
impl RustRuntime {
|
||||
pub fn inner(&self) -> &Arc<RustRuntimeInner> {
|
||||
impl Deref for RustRuntime {
|
||||
type Target = RustRuntimeInner;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user