sui_indexer_alt_jsonrpc/
context.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use std::sync::Arc;
use std::time::Duration;

use async_graphql::dataloader::DataLoader;
use prometheus::Registry;
use sui_package_resolver::Resolver;
use sui_pg_db::DbArgs;
use tokio_util::sync::CancellationToken;
use url::Url;

use crate::{
    config::RpcConfig,
    data::{
        bigtable_reader::BigtableReader,
        error::Error,
        kv_loader::KvLoader,
        package_resolver::{DbPackageStore, PackageCache, PackageResolver},
        pg_reader::PgReader,
    },
    metrics::RpcMetrics,
};

/// A bundle of different interfaces to data, for use by JSON-RPC method implementations.
#[derive(Clone)]
pub(crate) struct Context {
    /// Direct access to the database, for running SQL queries.
    pg_reader: PgReader,

    /// Access to the database for performing point look-ups. Access is through the same connection
    /// pool as `reader`, but this interface groups multiple point lookups into a single database
    /// query.
    pg_loader: Arc<DataLoader<PgReader>>,

    /// Access to the kv store for performing point look-ups. This may either be backed by Bigtable
    /// or Postgres db, depending on the configuration.
    kv_loader: KvLoader,

    /// Access to the database for accessing information about types from their packages (again
    /// through the same connection pool as `reader`).
    package_resolver: PackageResolver,

    /// Access to the RPC's metrics.
    metrics: Arc<RpcMetrics>,

    /// Access to the RPC's configuration.
    config: Arc<RpcConfig>,
}

impl Context {
    /// Set-up access to the stores through all the interfaces available in the context. If
    /// `bigtable_instance` is set, KV lookups will be sent to it, otherwise they will be sent to
    /// the `database. If `database_url` is `None`, the interfaces will be set-up but will fail to
    /// accept any connections.
    pub(crate) async fn new(
        database_url: Option<Url>,
        bigtable_instance: Option<String>,
        db_args: DbArgs,
        config: RpcConfig,
        metrics: Arc<RpcMetrics>,
        slow_request_threshold: Duration,
        registry: &Registry,
        cancel: CancellationToken,
    ) -> Result<Self, Error> {
        let pg_reader = PgReader::new(
            database_url,
            db_args,
            metrics.clone(),
            registry,
            cancel,
            slow_request_threshold,
        )
        .await?;
        let pg_loader = Arc::new(pg_reader.as_data_loader());

        let kv_loader = if let Some(instance_id) = bigtable_instance {
            let bigtable_reader =
                BigtableReader::new(instance_id, registry, slow_request_threshold).await?;
            KvLoader::new_with_bigtable(Arc::new(bigtable_reader.as_data_loader()))
        } else {
            KvLoader::new_with_pg(pg_loader.clone())
        };

        let store = PackageCache::new(DbPackageStore::new(pg_loader.clone()));
        let package_resolver = Arc::new(Resolver::new_with_limits(
            store,
            config.package_resolver.clone(),
        ));

        Ok(Self {
            pg_reader,
            pg_loader,
            kv_loader,
            package_resolver,
            metrics,
            config: Arc::new(config),
        })
    }

    /// For performing arbitrary SQL queries on the Postgres db.
    pub(crate) fn pg_reader(&self) -> &PgReader {
        &self.pg_reader
    }

    /// For performing point look-ups on the Postgres db only.
    pub(crate) fn pg_loader(&self) -> &Arc<DataLoader<PgReader>> {
        &self.pg_loader
    }

    /// For performing point look-ups on the kv store.
    /// Depends on the configuration of the indexer, the kv store may be backed by
    /// eitherBigtable or Postgres.
    pub(crate) fn kv_loader(&self) -> &KvLoader {
        &self.kv_loader
    }

    /// For querying type and function signature information.
    pub(crate) fn package_resolver(&self) -> &PackageResolver {
        &self.package_resolver
    }

    /// Access to the RPC metrics.
    pub(crate) fn metrics(&self) -> &RpcMetrics {
        self.metrics.as_ref()
    }

    /// Access to the RPC configuration.
    pub(crate) fn config(&self) -> &RpcConfig {
        self.config.as_ref()
    }
}