cube-js / cube-js/cube

Cube+Cubestore - pre-aggregation only built for one tenant

Open
#9,132 3 comments 0 reactions 1 assignee Claimed by @igorlukanin View on GitHub
pre-aggregations question
Dominant language
Rust
Stars
20.8k
Forks
2.1k
Avg merge
1d 2h
Merged PRs (30d)
181

Description

**Describe the bug**

I am working on a production deployment of Cube+Cubestore with multi-tenancy. I use pre-aggregations in some models, which are working fine. However, one specific pre-aggregation is currently only being built for one tenant, which causes other tenant's queries that hit it to fail, with the API claiming that it can't find the expected pre-aggregation table:

```
Error: No pre-aggregation partitions were built yet for the pre-aggregation serving this query and this API instance wasn't set up to build pre-aggregations. Please make sure your refresh worker is configured correctly, running, pre-aggregation tables are built and all pre-aggregation refresh settings like timezone match. Expected table name patterns: pre_aggregations_.events_events_by_category_and_city*_5lcntksd_*
```

I can't seem to figure out the reason for this. Looking at `cubestore` logs, I see the trail of building all the other pre-aggregations for all tenants, but the specific one I am talking about is never uploaded for the tenants in question. Cube refresh workers also do not show any errors related to this pre-aggregation.

The following things are making the problem here unclear to me:

1. The rest of the cube is working -> thus it is able to find the data in the origin database, and filter it correctly by tenant
2. The rest of the pre-aggregations are working -> thus my `preAggregationsSchema` and `scheduledRefreshContexts` should be OK otherwise I would have no pre-aggregations (right?)
3. The pre-aggregation works in development mode, when connected to the same sources and tenants -> not 100% sure here, but this should mean that the pre-aggregation is able to run on the data
4. It works in **one** tenant -> thus it can't be that somehow the pre-aggregation isn't loaded in the production environment

I have tried:

- Deleting all cubestore cache and rebuilding everything from scratch -> no effect
- Configuring the instance with only a single tenant (which currently does not have the pre-aggregation) -> also does not build the pre-aggregation

**To Reproduce**

Steps to reproduce the behavior:
1. Create a multi tenant cube configuration, with a model that has a pre-aggregation
2. Deploy the configuration in a production environment, using workers+cubestore
3. Make a query using the pre-aggregation on two different tenants
4. One tenant works, the other one does not

**Expected behavior**

Both tenants should have the pre-aggregation built.

**Minimally reproducible Cube Schema**

```yaml
cubes:
- name: events
sql_table: '"{COMPILE_CONTEXT.securityContext.tenantId}".events'
data_source: default
public: false

dimensions:
- name: event_id
type: number
sql: id
primary_key: true

- name: event_status
type: string
sql: status

measures:
- name: num_events
type: count
drill_members:
- categories.category_name
- cities.city_name
- event_status

pre_aggregations:
- name: events_by_category_and_city
measures:
- CUBE.num_events
dimensions:
- categories.category_name
- cities.city_name

- name: categories
sql_table: '"{COMPILE_CONTEXT.securityContext.tenantId}".categories'
data_source: default
public: false

dimensions:
- name: category_id
type: number
sql: id
primary_key: true

- name: category_name
type: string
sql: name

- name: cities
sql_table: '"{COMPILE_CONTEXT.securityContext.tenantId}".cities'
data_source: default
public: false

dimensions:
- name: city_id
type: number
sql: id
primary_key: true

- name: city_name
type: string
sql: name
```

**Version:**
v1.1.7

**Additional context**

Here is my `cube.js` configuration file:

```javascript
const TENANTS = process.env.CUBEJS_TENANTS
? process.env.CUBEJS_TENANTS.split(",")
: [];

module.exports = {
contextToAppId: ({ securityContext }) =>
`CUBE_APP_${securityContext.tenantId}`,
contextToOrchestratorId: ({ securityContext }) =>
`CUBE_APP_${securityContext.tenantId}`,
scheduledRefreshContexts: () =>
TENANTS.map((tenantId) => ({
securityContext: {
tenantId,
},
})),
preAggregationsSchema: ({ securityContext }) => {
return `pre_aggregations_${securityContext.tenantId.replace(/-/g, "_")}`;
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.