Skip to content

Commit

Permalink
Introduce nativelink-bridge
Browse files Browse the repository at this point in the history
This is a fast prototype for subscribing to the redis/dragonflydb "build_events" channel and
decode them properly via protobuf and fires them via websocket to the browser.
  • Loading branch information
SchahinRohani committed Nov 6, 2024
1 parent ac44984 commit bcbf293
Show file tree
Hide file tree
Showing 19 changed files with 755 additions and 0 deletions.
3 changes: 3 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@
};
};

nativelink-bridge = pkgs.callPackage ./web/bridge/image.nix {inherit buildImage pullImage pkgs;};

nativelink-worker-init = pkgs.callPackage ./tools/nativelink-worker-init.nix {inherit buildImage self nativelink-image;};

rbe-autogen = pkgs.callPackage ./local-remote-execution/rbe-autogen.nix {
Expand Down Expand Up @@ -419,6 +421,7 @@
nativelink-worker-init
nativelink-x86_64-linux
publish-ghcr
nativelink-bridge
;
default = nativelink;

Expand Down
177 changes: 177 additions & 0 deletions nativelink-config/examples/basic_bes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
{
"stores": {
"AC_MAIN_STORE": {
"filesystem": {
"content_path": "/tmp/nativelink/data-worker-test/content_path-ac",
"temp_path": "/tmp/nativelink/data-worker-test/tmp_path-ac",
"eviction_policy": {
"max_bytes": 100000000000
}
}
},
"BEP_STORE": {
"redis_store": {
"addresses": [
"redis://@localhost:6379/0"
],
"response_timeout_s": 5,
"connection_timeout_s": 5,
"experimental_pub_sub_channel": "build_event",
"key_prefix": "nativelink:",
"mode": "standard"
}
},
"WORKER_FAST_SLOW_STORE": {
"fast_slow": {
"fast": {
"filesystem": {
"content_path": "/tmp/nativelink/data-worker-test/content_path-cas",
"temp_path": "/tmp/nativelink/data-worker-test/tmp_path-cas",
"eviction_policy": {
"max_bytes": 100000000000
}
}
},
"slow": {
"noop": {}
}
}
}
},
"schedulers": {
"MAIN_SCHEDULER": {
"simple": {
"supported_platform_properties": {
"cpu_count": "minimum",
"memory_kb": "minimum",
"network_kbps": "minimum",
"disk_read_iops": "minimum",
"disk_read_bps": "minimum",
"disk_write_iops": "minimum",
"disk_write_bps": "minimum",
"shm_size": "minimum",
"gpu_count": "minimum",
"gpu_model": "exact",
"cpu_vendor": "exact",
"cpu_arch": "exact",
"cpu_model": "exact",
"kernel_version": "exact",
"OSFamily": "priority",
"container-image": "priority"
}
}
}
},
"workers": [
{
"local": {
"worker_api_endpoint": {
"uri": "grpc://127.0.0.1:50062"
},
"cas_fast_slow_store": "WORKER_FAST_SLOW_STORE",
"upload_action_result": {
"ac_store": "AC_MAIN_STORE"
},
"work_directory": "/tmp/nativelink/work",
"platform_properties": {
"cpu_count": {
"values": [
"16"
]
},
"memory_kb": {
"values": [
"500000"
]
},
"network_kbps": {
"values": [
"100000"
]
},
"cpu_arch": {
"values": [
"x86_64"
]
},
"OSFamily": {
"values": [
""
]
},
"container-image": {
"values": [
""
]
}
}
}
}
],
"servers": [
{
"name": "public",
"listener": {
"http": {
"socket_address": "0.0.0.0:50052"
}
},
"services": {
"cas": {
"main": {
"cas_store": "WORKER_FAST_SLOW_STORE"
}
},
"ac": {
"main": {
"ac_store": "AC_MAIN_STORE"
}
},
"execution": {
"main": {
"cas_store": "WORKER_FAST_SLOW_STORE",
"scheduler": "MAIN_SCHEDULER"
}
},
"capabilities": {
"main": {
"remote_execution": {
"scheduler": "MAIN_SCHEDULER"
}
}
},
"bytestream": {
"cas_stores": {
"main": "WORKER_FAST_SLOW_STORE"
}
}
}
},
{
"name": "private_workers_servers",
"listener": {
"http": {
"socket_address": "0.0.0.0:50062"
}
},
"services": {
"experimental_prometheus": {
"path": "/metrics"
},
"experimental_bep": {
"store": "BEP_STORE"
},
"worker_api": {
"scheduler": "MAIN_SCHEDULER"
},
"admin": {},
"health": {
"path": "/status"
}
}
}
],
"global": {
"max_open_files": 512
}
}
1 change: 1 addition & 0 deletions tools/pre-commit-hooks.nix
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ in {

# Bun binary lockfile
"web/platform/bun.lockb"
"web/bridge/bun.lockb"
];
enable = true;
types = ["binary"];
Expand Down
5 changes: 5 additions & 0 deletions web/bridge/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
REDIS_URL=redis://localhost:6379
NATIVELINK_PUB_SUB_CHANNEL=build_event
POSTGRES_URL=postgres://username:password@host:port/database
WEBSOCKET_PORT=8080
HTTP_PORT=3001
30 changes: 30 additions & 0 deletions web/bridge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Logs
logs

# Caches
.cache

# Runtime data
pids
_.pid
_.seed
*.pid.lock

# Dependency directories
node_modules/

# TypeScript cache
*.tsbuildinfo

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# distribution directory
dist

# temporary files
.temp
79 changes: 79 additions & 0 deletions web/bridge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# NativeLink Bridge (Experimental)

Make sure you are running an instance of Redis or DragonflyDB in your network.

For DragonflyDB inside docker run:

```bash
docker run \
-d --name some-dragonfly \
-p 6379:6379 \
--ulimit memlock=-1 \
docker.dragonflydb.io/dragonflydb/dragonfly

```

For Redis inside docker run:

```bash
docker run -d --name some-redis \
-p 6379:6379 \
redis
```

Set the Redis URL and the NativeLink pub sub channel ENV variables in `.env` as defined in the `.env.example`


The Redis URL format: 'redis://alice:foobared@awesome.redis.server:6380'

The NativeLink pub sub channel ENV variable should match `experimental_pub_sub_channel` inside `nativelink-config/example/basic_bes.json`.

Make sure you have set also the `key_prefix` in `nativelink-config/example/basic_bes.json`

## You need 4 Components + Redis

### 1. NativeLink

Start an instance of NativeLink with the basic_bes.json inside the `nativelink-config/example/basic_bes.json`.

### 2. NativeLink Web Bridge

Install the dependencies and run the bridge:

```bash
bun i && bun run index.ts
```

### 3. NativeLink Web UI

Inside the web/ui directory run:

```bash
bun i & bun dev
```

Now you can open http://localhost:4321.


### 4. Bazel

Now you can run your Bazel build with NativeLink and see it in real-time going into the web app

Include this in your .bazelrc
```bash
bazel clean && bazel build \
--remote_cache=grpc://localhost:50051 \
--remote_executor=grpc://localhost:50051 \
--bes_backend=grpc://localhost:50061 \
--bes_results_url=http://localhost:4321/builds \
--bes_upload_mode=fully_async \
--build_event_publish_all_actions=true \
//local-remote-execution/examples:hello_lre
```

Make sure to use the right IP, if it's not hosted on `localhost`


```bash
bazel build some-target
```
Binary file added web/bridge/bun.lockb
Binary file not shown.
32 changes: 32 additions & 0 deletions web/bridge/image.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
pkgs,
buildImage,
...
}: let
# NativeLink Bridge
nativelink-bridge = pkgs.stdenv.mkDerivation {
name = "nativelink-bridge";
src = ./.;
buildInputs = [pkgs.bun];
installPhase = ''
mkdir -p $out
cp -r $src/* $out
'';
};
in
buildImage {
name = "nativelink-bridge";

# Container configuration
config = {
WorkingDir = "${nativelink-bridge}";
Entrypoint = ["${pkgs.bun}/bin/bun" "run" "index.ts"];
ExposedPorts = {
"8080/tcp" = {};
};
Labels = {
"org.opencontainers.image.description" = "A simple Bun environment image";
"org.opencontainers.image.title" = "Bun Environment";
};
};
}
3 changes: 3 additions & 0 deletions web/bridge/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { start } from './src';

start().catch(err => console.error(err));
22 changes: 22 additions & 0 deletions web/bridge/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "nativelink-bridge",
"version": "0.5.3",
"module": "index.ts",
"type": "module",
"dependencies": {
"drizzle-orm": "^0.36.0",
"postgres": "^3.4.5",
"protobufjs": "^7.4.0",
"redis": "^4.7.0"
},
"devDependencies": {
"@types/bun": "^1.1.8",
"drizzle-kit": "^0.27.1"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"trustedDependencies": [
"protobufjs"
]
}
9 changes: 9 additions & 0 deletions web/bridge/src/db/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { drizzle } from "drizzle-orm/postgres-js";

const postgresConfig = process.env.POSTGRES_URL || "postgres://user:password@localhost:5432/postgres"

const db = drizzle(postgresConfig);

export const build_data = await db.execute('select * from build_data');

export { db };
Loading

0 comments on commit bcbf293

Please sign in to comment.