ydb-platform / ydb-rs-sdk

Apache License 2.0
52 stars 18 forks source link

The driver hangs up while connecto to ydb 23-1-26 #144

Closed DirectX closed 1 year ago

DirectX commented 1 year ago

I've not been able to use Rust driver as in examples on any of three tested Linux machines: Ubuntu 21.04 hirsute server, Ubuntu 23.04 lunar desktop, Debian GNU/Linux 11 (bullseye) server. After making application as in examples the program is being stuck at client.wait().await?; line. Docker logs shows at the moment the error:

ydb-local  | :GRPC_LIBRARY ERROR: Error parsing metadata: error=invalid value key=:scheme value=grpc

This behavior is actual for YDB local binary installation, local Docker installation as well as for YDB managed service.

Steps to reproduce

Prerequisites

YDB CLI

user@host:~$ curl -sSL https://storage.yandexcloud.net/yandexcloud-ydb/install.sh | bash
Downloading ydb 2.4.0
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 58.0M  100 58.0M    0     0  63.3M      0 --:--:-- --:--:-- --:--:-- 63.2M
YDB CLI 2.4.0

ydb PATH has been added to your '/home/user/.bashrc' profile
To complete installation, start a new shell (exec -l $SHELL) or type 'source "/home/user/.bashrc"' in the current one

user@host:~$ source /home/user/.bashrc 
user@host:~$ ydb version
YDB CLI 2.4.0

YDB Docker Installation

docker-compose.ydb.yaml

version: '3.2'

services:
  ydb-local:
    image: cr.yandex/yc/yandex-docker-local-ydb:latest
    container_name: ydb-local
    restart: always
    hostname: localhost
    ports:
      - 2135:2135
      - 2136:2136
      - 8765:8765
    volumes:
      - ./.data/ydb/data:/ydb_data
      - ./.data/ydb/certs:/ydb_certs
    environment:
      - YDB_DEFAULT_LOG_LEVEL=NOTICE
      - GRPC_TLS_PORT=2135
      - GRPC_PORT=2136
      - MON_PORT=8765
user@host:~$ docker compose -f docker-compose.ydb.yaml up -d
Creating network "ydb-demo_default" with the default driver
Pulling ydb-local (cr.yandex/yc/yandex-docker-local-ydb:latest)...
latest: Pulling from yc/yandex-docker-local-ydb
325d69979d33: Pull complete
bd14f4d56a9c: Pull complete
Digest: sha256:97b68a0e8de5c76d1b5efea1ea65ccfdd8affe134e6acf93944c5e83ab8501bf
Status: Downloaded newer image for cr.yandex/yc/yandex-docker-local-ydb:latest
Creating ydb-local ... done

Checking CLI

user@host:~$ ydb -e grpc://localhost:2136 -d /local scheme ls -l
┌──────┬──────────────┬──────┬─────────┬──────────┬─────────────┐
| Type | Owner        | Size | Created | Modified | Name        |
├──────┼──────────────┼──────┼─────────┼──────────┼─────────────┤
| dir  | root@builtin |      |         |          | .sys_health |
| dir  |              |      |         |          | .sys        |
└──────┴──────────────┴──────┴─────────┴──────────┴─────────────┘

At this moment CLI access is working. Web UI Client http://localhost:8765 works as well. If testing local binary installation database name must be changed from /local to /Root/test.

Checking Rust Toolchain Version

user@host:~$ rustup show
Default host: x86_64-unknown-linux-gnu
rustup home:  /home/user/.rustup

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu (default)
1.70.0-x86_64-unknown-linux-gnu

active toolchain
----------------

stable-x86_64-unknown-linux-gnu (default)
rustc 1.70.0 (90c541806 2023-05-31)

YDB Demo Application

user@host:~$ cargo new ydb-demo
user@host:~$ cd ydb-demo
user@host:~/ydb-demo$ tree
├── Cargo.lock
├── Cargo.toml
└── src
    └── main.rs

Changes made to the default empty app:

Cargo.toml

[package]
name = "ydb-demo"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = { version = "1.28.2", features = ["full"]}
ydb = "0.6.0"

src/main.rs

use ydb::{ClientBuilder, YdbResult};

#[tokio::main]
async fn main() -> YdbResult<()> {
    println!("Starting...");
    let client = ClientBuilder::new_from_connection_string("grpc://localhost:2136?database=local")?
        .client()?;

    println!("Waiting...");
    client.wait().await?;
    println!("Done");

    Ok(())
}

Expected Result

user@host:~/ydb-demo$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.10s
     Running `target/debug/ydb-demo`
Starting...
Waiting...
Done

Actual Result

user@host:~/ydb-demo$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.10s
     Running `target/debug/ydb-demo`
Starting...
Waiting...

Addition

The very same code written with Go YDB SDK on the same machines works perfectly fine without GRPC error on Doker side:

package main

import (
    "context"
    "log"
    "path"

    "github.com/ydb-platform/ydb-go-sdk/v3"
    "github.com/ydb-platform/ydb-go-sdk/v3/table"
    "github.com/ydb-platform/ydb-go-sdk/v3/table/options"
    "github.com/ydb-platform/ydb-go-sdk/v3/table/types"
)

func main() {
    log.Println("Starting...")

    ctx := context.Background()
    dsn := "grpc://localhost:2136?database=local"
    db, err := ydb.Open(ctx, dsn)
    if err != nil {
        panic(err)
    }
    defer db.Close(ctx)

    err = db.Table().Do(ctx,
        func(ctx context.Context, s table.Session) (err error) {
            return s.CreateTable(ctx, path.Join(db.Name(), "test"),
                options.WithColumn("id", types.TypeUint64),
                options.WithColumn("val", types.Optional(types.TypeUTF8)),
                options.WithPrimaryKeyColumn("id"),
            )
        },
    )
    if err != nil {
        panic(err)
    }

    err = db.Table().Do(ctx,
        func(ctx context.Context, s table.Session) (err error) {
            desc, err := s.DescribeTable(ctx, path.Join(db.Name(), "test"))
            if err != nil {
                return
            }
            log.Printf("> describe table: %s\n", desc.Name)
            for _, c := range desc.Columns {
                log.Printf("  > column, name: %s, %s\n", c.Type, c.Name)
            }
            return
        },
    )
    if err != nil {
        panic(err)
    }
}

Output:

$ go run .
2023/06/12 20:13:48 Starting...
2023/06/12 20:13:48 > describe table: test
2023/06/12 20:13:48   > column, name: Uint64, id
2023/06/12 20:13:48   > column, name: Optional<Utf8>, val

Rust equivalent:

use ydb::{ClientBuilder, YdbResult};

#[tokio::main]
async fn main() -> YdbResult<()> {
    println!("Starting...");
    let client = ClientBuilder::new_from_connection_string("grpc://localhost:2136?database=local")?
        .client()?;

    println!("Waiting...");
    client.wait().await?;
    println!("Done");

    let table_client = client.table_client();
    table_client
        .retry_execute_scheme_query("CREATE TABLE test (id Uint64 NOT NULL, val Utf8, PRIMARY KEY(id))")
        .await?;
    println!("Table ok");

    Ok(())
}

Output:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `target/debug/ydb-demo`
Starting...
Waiting...

Output after intentional commenting out client.wait().await?; line:

$ cargo run
   Compiling ydb-demo v0.1.0 (/home/denis/projects/rust/experiments/ydb-demo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.50s
     Running `target/debug/ydb-demo`
Starting...
Waiting...
Done
Error: Custom("empty endpoint list for service: table_service")

what was expected.

DirectX commented 1 year ago

Here is experiment of setting up fresh environment from scratch on DigitalOcean's node (8 GB Memory / 160 GB Disk / FRA1 - Ubuntu 22.10 x64)

This uncut workflow is very same as described above + all necessary prerequisites for fresh LTS Ubuntu release. https://drive.google.com/file/d/1kiKFoRbQ2x_MuQkzfklc6efUN_wgvPOJ/view?usp=drive_link

If I'm wrong at any stage feel free to point this out with timestamp. If I miss some pitfall it's worth to mention in docs because it is not so obvious.

rekby commented 1 year ago

Hello, thanks for the issue, I will check it

rekby commented 1 year ago

@DirectX hello. Thanks for the issue.

I reproduce the problem with latest image, it will be fixed.

Now as workaround you can use image cr.yandex/yc/yandex-docker-local-ydb:stable-22-5 for tests.

DirectX commented 1 year ago

Hi, @rekby,

Thanks for solution. Workaround works fine. Waiting for next release.

rekby commented 1 year ago

The problem fixed in v0.6.1.