Skip to content

Commit 3822107

Browse files
authored
feat(api-gateway): Async native query results transformations (#8961)
* create a basic cubeorchestrator project structure * wip * move flatbuffer schema/code to separate crate * implement parse_cubestore_ws_result * add cubeorchestrator/parse_cubestore_ws_result_message export * use native parseCubestoreResultMessage * init hashmap with capacity * cargo fmt * some optimizations and improvements * a bit optimized version * use cx.execute_scoped for optimization * a bit more rust idiomatic code * put native parseCubestoreResultMessage behind the flag * tiny improvement * cargo fmt * cargo fmt * cargo clippy fix * update cubestore Dockerfile * cargo fmt * update cubestore Docker builds * introduce CubeStoreResult struct * create CubeStoreResultWrapper class and switch to lazy evaluation of results set * add resToRawResultFn in API GW * cargo fmt * update resToResultFn * call prepareAnnotation later * remove bytes * add cached flag to CubeStoreResultWrapper * convert core data types from api gateway * implement transformData and related helpers * cargo fmt * down chrono to same version as in cubesql (0.4.31) * fail fast in api gw load() * update cargo.lock (syn crate) * linter fix * implement get_query_granularities & get_pivot_query * prepare transformQueryData native wrapper * small optimization: do not use native parsing for short messages * refactor transformValue and related * types restructure * debug and fix native transform_data() * lazy transformData evaluation * omplement get_final_cubestore_result & get_final_cubestore_result_multi in native * cargo fmt * cargo clippy fix * refactor getVanillaRow * implement get_final_cubestore_result_array() native * fix native response flow for sqlApiLoad * add postgres with native cubestore results driver tests * Build native (without Python) in drivers tests * workaround for native build in testings-drivers * small improvements in CubeStoreResultWrapper * make parse_cubestore_ws_result_message async * make all native cubestore_result_transform functions async * cargo fmt * refactor results transformations * yarn sync * implement custom deserializer from JS Value to rust and updated the cubestore result transformations with it * refactor json_to_array_buffer() * a bit of refactoring * code rearrangement * switch to use DBResponsePrimitive instead of just Strings * refactoring * always use transform data native for all results * fix dtos for native query processing (thnx unit tests) * cache loadNative * remove not needed anymore native.transformQueryData * add Build native for unit tests in CI * refactor serde annotations * remove unused * annotate native query results processing functions * add Build native for unit tests in CI for Debian without pushing * add few unit tests * fix some tests * attempt to fix native build/test in docker-dev CI * fix empty result set issue * another fix in datetime parsing * another fix in deserialization * another fix in datetime parsing * update postgres-native-cubestore-response-full.test.ts.snap * another fix in deserialization * cargo fmt * another fix in datetime parsing * update postgres-native-cubestore-response-full.test.ts.snap * attempt to fix native build/test in docker-dev CI * add some comments * edits in result processing when streaming * fix native response processing via websocket * fix yarn lock * attempt to fix native build/test in cloud integration tests in CI * recreated unit tests for transform data in native * run rust unit tests on push * commented out cargo fmt/build/test for cubesql, cubesqlplanner * remove transformdata JS implementation * refactor push CI jobs * rename CubestoreResultWrapper → ResultWrapper * add isNative flag to ResultWrapper * rename getResultInternal → prepareResultTransformData * use ResultWrapper for all results * fix getArray in ResultWrapper * lint fix * encapsulate rootResultObject into ResultWrapper * add DataResult interface + implement it in result wrappers * add isWrapper property to wrappers * transform wrapped result later before returning the response * fix lint warn * fix async request porcessing * some node version fix * weird yarn.lock change. Wtf? * full transition of result native-js-native * fix @cubejs-backend/native version ref * refactor ResultWrapper constructor * fix string deserialize in transport * extend DataResult interface * support iterative access in ResultWrapper * refactor ResultWrapper classes * pass ResultWrapper to native and offload transformData from the eventloop * remove obsolete getFinalQueryResultArray * fix ws api subscriptionServer results processing * pass SchemaRef to load methods. * trying to fix flaky ws failing tests * remove cubeorchestrator dependency from cubesql * rewrite all load api calls to return RecordBatch * fix @cubejs-backend/native version ref after rebase * set prototype of ResultWrapper proxy to class prototype * fix linter warnings * fix yarn.lock * linter fix * Set CUBEJS_TESSERACT_ORCHESTRATOR: true for all tests workflows * fix old refs after rebase * update integration-cubestore job with the build of backend-native * remove postgres-native-cubestore-response from testing drivers as we turnon new orchestrator for all tests
1 parent db3b0fd commit 3822107

File tree

87 files changed

+5531
-2241
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+5531
-2241
lines changed

.github/workflows/cloud.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ on:
2525
- 'package.json'
2626
- 'yarn.lock'
2727

28+
env:
29+
CUBEJS_TESSERACT_ORCHESTRATOR: true
30+
2831
jobs:
2932
latest-tag-sha:
3033
runs-on: ubuntu-20.04
@@ -59,15 +62,31 @@ jobs:
5962
matrix:
6063
node-version: [ 20.x ]
6164
db: [ 'athena', 'bigquery', 'snowflake' ]
65+
target: [ "x86_64-unknown-linux-gnu" ]
6266
fail-fast: false
6367

6468
steps:
6569
- name: Checkout
6670
uses: actions/checkout@v4
71+
- name: Install Rust
72+
uses: actions-rust-lang/setup-rust-toolchain@v1
73+
with:
74+
toolchain: nightly-2024-07-15
75+
# override: true # this is by default on
76+
rustflags: ""
77+
components: rustfmt
78+
target: ${{ matrix.target }}
6779
- name: Install Node.js ${{ matrix.node-version }}
6880
uses: actions/setup-node@v4
6981
with:
7082
node-version: ${{ matrix.node-version }}
83+
- name: Install cargo-cp-artifact
84+
run: npm install -g [email protected]
85+
- uses: Swatinem/rust-cache@v2
86+
with:
87+
workspaces: ./packages/cubejs-backend-native
88+
key: native-${{ runner.OS }}-${{ matrix.target }}
89+
shared-key: native-${{ runner.OS }}-${{ matrix.target }}
7190
- name: Get yarn cache directory path
7291
id: yarn-cache-dir-path
7392
run: echo "dir=$(yarn cache dir)" >> "$GITHUB_OUTPUT"
@@ -87,6 +106,8 @@ jobs:
87106
run: yarn build
88107
- name: Lerna tsc
89108
run: yarn tsc
109+
- name: Build native (no python)
110+
run: cd packages/cubejs-backend-native && npm run native:build-release
90111
- name: Run Integration tests for ${{ matrix.db }} matrix
91112
timeout-minutes: 30
92113
env:

.github/workflows/drivers-tests.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ on:
5656
- 'packages/cubejs-backend-native/**'
5757
- 'rust/cubesql/**'
5858

59+
env:
60+
CUBEJS_TESSERACT_ORCHESTRATOR: true
61+
5962
jobs:
6063
latest-tag-sha:
6164
runs-on: ubuntu-20.04
@@ -117,8 +120,8 @@ jobs:
117120
- uses: Swatinem/rust-cache@v2
118121
with:
119122
workspaces: ./packages/cubejs-backend-native
120-
key: native-${{ runner.OS }}-x86_64-unknown-linux-gnu
121-
shared-key: native-${{ runner.OS }}-x86_64-unknown-linux-gnu
123+
key: native-${{ runner.OS }}-${{ matrix.target }}
124+
shared-key: native-${{ runner.OS }}-${{ matrix.target }}
122125
- name: Build native (fallback)
123126
if: (matrix.python-version == 'fallback')
124127
env:
@@ -165,7 +168,12 @@ jobs:
165168
uses: actions/download-artifact@v4
166169
with:
167170
name: backend-native
168-
path: packages/cubejs-backend-native/
171+
path: packages/cubejs-backend-native
172+
# current .dockerignore prevents use of native build
173+
- name: Unignore native from .dockerignore
174+
run: |
175+
grep -v -E "packages/cubejs-backend-native/((native)|(index.node))" .dockerignore > .dockerignore.tmp
176+
mv .dockerignore.tmp .dockerignore
169177
- name: Build and push
170178
uses: docker/build-push-action@v6
171179
with:

.github/workflows/master.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ on:
1616
- 'rust/cubesql/**'
1717
branches:
1818
- master
19+
env:
20+
CUBEJS_TESSERACT_ORCHESTRATOR: true
1921
jobs:
2022
latest-tag-sha:
2123
runs-on: ubuntu-20.04

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ jobs:
552552
- name: Push to Docker Hub
553553
uses: docker/build-push-action@v6
554554
with:
555-
context: ./rust/cubestore/
555+
context: ./rust/
556556
file: ./rust/cubestore/Dockerfile
557557
platforms: ${{ matrix.platforms }}
558558
build-args: ${{ matrix.build-args }}

.github/workflows/push.yml

Lines changed: 108 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ on:
99
- 'packages/**'
1010
- 'rust/cubestore/**'
1111
- 'rust/cubesql/**'
12+
- 'rust/cubenativeutils/**'
13+
- 'rust/cubeorchestrator/**'
14+
- 'rust/cubeshared/**'
15+
- 'rust/cubesqlplanner/**'
1216
- '.eslintrc.js'
1317
- '.prettierrc'
1418
- 'package.json'
@@ -24,13 +28,20 @@ on:
2428
- 'packages/**'
2529
- 'rust/cubestore/**'
2630
- 'rust/cubesql/**'
31+
- 'rust/cubenativeutils/**'
32+
- 'rust/cubeorchestrator/**'
33+
- 'rust/cubeshared/**'
34+
- 'rust/cubesqlplanner/**'
2735
- '.eslintrc.js'
2836
- '.prettierrc'
2937
- 'package.json'
3038
- 'lerna.json'
3139
- 'rollup.config.js'
3240
- 'yarn.lock'
3341

42+
env:
43+
CUBEJS_TESSERACT_ORCHESTRATOR: true
44+
3445
jobs:
3546
unit:
3647
runs-on: ubuntu-20.04
@@ -95,14 +106,15 @@ jobs:
95106
command: yarn install --frozen-lockfile
96107
- name: Lerna tsc
97108
run: yarn tsc
109+
- name: Build native (no python)
110+
run: cd packages/cubejs-backend-native && npm run native:build-release
98111
- name: Build client
99112
run: yarn build
100113
- name: Build cubejs-backend-native (with Python)
101114
run: yarn run native:build-release-python
102115
working-directory: ./packages/cubejs-backend-native
103116
env:
104117
PYO3_PYTHON: python${{ matrix.python-version }}
105-
106118
- name: Lerna test
107119
run: yarn lerna run --concurrency 1 --stream --no-prefix unit
108120
# - uses: codecov/codecov-action@v1
@@ -111,6 +123,21 @@ jobs:
111123
# files: ./packages/*/coverage/clover.xml
112124
# flags: cube-backend
113125
# verbose: true # optional (default = false)
126+
- name: Cargo test cubeorchestrator
127+
run: |
128+
cargo test --manifest-path rust/cubeorchestrator/Cargo.toml -j 1
129+
- name: Cargo test cubenativeutils
130+
run: |
131+
cargo test --manifest-path rust/cubenativeutils/Cargo.toml -j 1
132+
- name: Cargo test cubeshared
133+
run: |
134+
cargo test --manifest-path rust/cubeshared/Cargo.toml -j 1
135+
# - name: Cargo test cubesql
136+
# run: |
137+
# cargo test --manifest-path rust/cubesql/Cargo.toml -j 1
138+
# - name: Cargo test cubesqlplanner
139+
# run: |
140+
# cargo test --manifest-path rust/cubesqlplanner/cubesqlplanner/Cargo.toml -j 1
114141

115142
lint:
116143
runs-on: ubuntu-20.04
@@ -159,6 +186,21 @@ jobs:
159186
run: yarn lint:npm
160187
- name: Lerna lint
161188
run: yarn lerna run --concurrency 1 lint
189+
- name: Cargo fmt cubeorchestrator
190+
run: |
191+
cargo fmt --manifest-path rust/cubeorchestrator/Cargo.toml -- --check
192+
- name: Cargo fmt cubenativeutils
193+
run: |
194+
cargo fmt --manifest-path rust/cubenativeutils/Cargo.toml -- --check
195+
- name: Cargo fmt cubeshared
196+
run: |
197+
cargo fmt --manifest-path rust/cubeshared/Cargo.toml -- --check
198+
# - name: Cargo fmt cubesql
199+
# run: |
200+
# cargo fmt --manifest-path rust/cubesql/Cargo.toml -- --check
201+
# - name: Cargo fmt cubesqlplanner
202+
# run: |
203+
# cargo fmt --manifest-path rust/cubesqlplanner/cubesqlplanner/Cargo.toml -- --check
162204

163205
build:
164206
runs-on: ubuntu-20.04
@@ -211,6 +253,21 @@ jobs:
211253
run: yarn lerna run --concurrency 1 build
212254
env:
213255
NODE_OPTIONS: --max_old_space_size=4096
256+
- name: Cargo build cubeorchestrator
257+
run: |
258+
cargo build --manifest-path rust/cubeorchestrator/Cargo.toml -j 4
259+
- name: Cargo build cubenativeutils
260+
run: |
261+
cargo build --manifest-path rust/cubenativeutils/Cargo.toml -j 4
262+
- name: Cargo build cubeshared
263+
run: |
264+
cargo build --manifest-path rust/cubeshared/Cargo.toml -j 4
265+
# - name: Cargo build cubesql
266+
# run: |
267+
# cargo build --manifest-path rust/cubesql/Cargo.toml -j 4
268+
# - name: Cargo build cubesqlplanner
269+
# run: |
270+
# cargo build --manifest-path rust/cubesqlplanner/cubesqlplanner/Cargo.toml -j 4
214271

215272
build-cubestore:
216273
needs: [latest-tag-sha]
@@ -276,6 +333,13 @@ jobs:
276333
df -h
277334
- name: Checkout
278335
uses: actions/checkout@v4
336+
- name: Install Rust
337+
uses: actions-rust-lang/setup-rust-toolchain@v1
338+
with:
339+
toolchain: nightly-2024-07-15
340+
# override: true # this is by default on
341+
rustflags: ""
342+
components: rustfmt
279343
- name: Install Node.js ${{ matrix.node-version }}
280344
uses: actions/setup-node@v4
281345
with:
@@ -305,6 +369,9 @@ jobs:
305369
command: yarn install --frozen-lockfile
306370
- name: Lerna tsc
307371
run: yarn tsc
372+
- name: Build cubejs-backend-native (without Python)
373+
run: yarn run native:build-release
374+
working-directory: ./packages/cubejs-backend-native
308375
- name: Download cubestored-x86_64-unknown-linux-gnu-release artifact
309376
uses: actions/download-artifact@v4
310377
with:
@@ -539,6 +606,8 @@ jobs:
539606
- 5000:5000
540607
strategy:
541608
matrix:
609+
node-version: [ 20 ]
610+
target: [ "x86_64-unknown-linux-gnu" ]
542611
dockerfile:
543612
- dev.Dockerfile
544613
include:
@@ -565,21 +634,29 @@ jobs:
565634
df -h
566635
- name: Checkout
567636
uses: actions/checkout@v4
568-
- name: Set up QEMU
569-
uses: docker/setup-qemu-action@v3
570-
- name: Build image
571-
uses: docker/build-push-action@v6
572-
timeout-minutes: 30
637+
- name: Install Rust
638+
uses: actions-rust-lang/setup-rust-toolchain@v1
573639
with:
574-
context: .
575-
file: ./packages/cubejs-docker/${{ matrix.dockerfile }}
576-
platforms: linux/amd64
577-
push: true
578-
tags: localhost:5000/cubejs/cube:${{ matrix.tag }}
579-
- name: Use Node.js 20.x
640+
toolchain: nightly-2024-07-15
641+
# override: true # this is by default on
642+
rustflags: ""
643+
components: rustfmt
644+
target: ${{ matrix.target }}
645+
- name: Install Node.js ${{ matrix.node-version }}
580646
uses: actions/setup-node@v4
581647
with:
582-
node-version: 20.x
648+
node-version: ${{ matrix.node-version }}
649+
- name: Install Yarn
650+
run: npm install -g yarn
651+
- name: Set Yarn version
652+
run: yarn policies set-version v1.22.22
653+
- name: Install cargo-cp-artifact
654+
run: npm install -g [email protected]
655+
- uses: Swatinem/rust-cache@v2
656+
with:
657+
workspaces: ./packages/cubejs-backend-native
658+
key: native-${{ runner.OS }}-${{ matrix.target }}
659+
shared-key: native-${{ runner.OS }}-${{ matrix.target }}
583660
- name: Get yarn cache directory path
584661
id: yarn-cache-dir-path
585662
run: echo "dir=$(yarn cache dir)" >> "$GITHUB_OUTPUT"
@@ -591,8 +668,6 @@ jobs:
591668
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
592669
restore-keys: |
593670
${{ runner.os }}-yarn-
594-
- name: Set Yarn version
595-
run: yarn policies set-version v1.22.22
596671
- name: Yarn install
597672
uses: nick-fields/retry@v3
598673
env:
@@ -607,6 +682,24 @@ jobs:
607682
run: yarn build
608683
- name: Lerna tsc
609684
run: yarn tsc
685+
- name: Build native (no python)
686+
run: cd packages/cubejs-backend-native && npm run native:build-release
687+
- name: Set up QEMU
688+
uses: docker/setup-qemu-action@v3
689+
# current .dockerignore prevents use of native build
690+
- name: Unignore native from .dockerignore
691+
run: |
692+
grep -v -E "packages/cubejs-backend-native/((native)|(index.node))" .dockerignore > .dockerignore.tmp
693+
mv .dockerignore.tmp .dockerignore
694+
- name: Build image
695+
uses: docker/build-push-action@v6
696+
timeout-minutes: 30
697+
with:
698+
context: .
699+
file: ./packages/cubejs-docker/${{ matrix.dockerfile }}
700+
platforms: linux/amd64
701+
push: true
702+
tags: localhost:5000/cubejs/cube:${{ matrix.tag }}
610703
- name: Testing CubeJS (container mode) via BirdBox
611704
run: |
612705
cd packages/cubejs-testing/

.github/workflows/rust-cubestore-master.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ jobs:
151151
- name: Push to Docker Hub
152152
uses: docker/build-push-action@v6
153153
with:
154-
context: ./rust/cubestore
154+
context: ./rust
155155
file: ./rust/cubestore/Dockerfile
156156
platforms: ${{ matrix.platforms }}
157157
build-args: ${{ matrix.build-args }}

.github/workflows/rust-cubestore.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ jobs:
9999
- name: Build only
100100
uses: docker/build-push-action@v6
101101
with:
102-
context: ./rust/cubestore/
102+
context: ./rust/
103103
file: ./rust/cubestore/Dockerfile
104104
platforms: ${{ matrix.platforms }}
105105
build-args: ${{ matrix.build-args }}

packages/cubejs-api-gateway/src/SubscriptionServer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const calcMessageLength = (message: unknown) => Buffer.byteLength(
1919
typeof message === 'string' ? message : JSON.stringify(message)
2020
);
2121

22-
export type WebSocketSendMessageFn = (connectionId: string, message: any) => void;
22+
export type WebSocketSendMessageFn = (connectionId: string, message: any) => Promise<void>;
2323

2424
export class SubscriptionServer {
2525
public constructor(
@@ -31,7 +31,7 @@ export class SubscriptionServer {
3131
}
3232

3333
public resultFn(connectionId: string, messageId: string, requestId: string | undefined) {
34-
return (message, { status } = { status: 200 }) => {
34+
return async (message, { status } = { status: 200 }) => {
3535
this.apiGateway.log({
3636
type: 'Outgoing network usage',
3737
service: 'api-ws',

0 commit comments

Comments
 (0)