Skip to content

Commit 3aead92

Browse files
committed
refat: deploy improvements
1 parent f25d66d commit 3aead92

File tree

8 files changed

+41
-138
lines changed

8 files changed

+41
-138
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ node_modules/
22
dist/
33
data/
44
draft/
5-
.env
5+
.env*
66
.terraform
77
.terraform.lock.hcl
88
.terraform.tfstate.lock.info

Dockerfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,7 @@ COPY --from=builder /app/src/kadena-server/config/schema.graphql ./dist/kadena-s
1515
COPY --from=builder /app/src/circulating-coins/ ./dist/circulating-coins/
1616
EXPOSE 3001
1717

18-
CMD ["node", "dist/index.js", "--graphql"]
18+
ARG NODE_MODE=graphql
19+
20+
# Use the build argument in CMD
21+
CMD ["sh", "-c", "node dist/index.js --${NODE_MODE}"]

deploy.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
3+
# Check if mode parameter is provided
4+
if [ -z "$1" ]; then
5+
echo "Error: Please provide a mode (graphql, streaming, or missing)"
6+
echo "Usage: ./deploy.sh <mode>"
7+
exit 1
8+
fi
9+
10+
MODE=$1
11+
12+
# Build the image with the specified mode
13+
docker build --build-arg NODE_MODE=$MODE --no-cache -t kadindexer-ecr:$MODE .
14+
15+
# Tag the image
16+
docker tag kadindexer-ecr:$MODE 325501467038.dkr.ecr.us-east-1.amazonaws.com/kadindexer-ecr:$MODE
17+
18+
# Push to ECR
19+
docker push 325501467038.dkr.ecr.us-east-1.amazonaws.com/kadindexer-ecr:$MODE

indexer/.env.template

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
NODE_API_URL=https://api.chainweb.com
2-
SYNC_BASE_URL="https://api.chainweb.com/chainweb/0.0"
3-
4-
SYNC_MIN_HEIGHT=0
5-
SYNC_FETCH_INTERVAL_IN_BLOCKS=100
6-
SYNC_NETWORK="mainnet01"
7-
KADENA_GRAPHQL_API_URL=localhost
8-
KADENA_GRAPHQL_API_PORT=3001
9-
10-
API_GATEWAY_URL=https://api.mainnet.kadindexer.io
11-
API_KADENA_URL=https://kadena.io
12-
131
DB_USERNAME=postgres
142
DB_PASSWORD=password
153
DB_NAME=indexer
16-
DB_HOST="YOUR_DB_HOST"
17-
DB_SSL_ENABLED=false
4+
DB_HOST=localhost
5+
DB_SSL_ENABLED=false
6+
7+
NODE_API_URL=http://localhost:1848
8+
SYNC_BASE_URL=http://localhost:1848/chainweb/0.0
9+
SYNC_NETWORK=mainnet01
10+
11+
# GraphQL Server Configuration
12+
KADENA_GRAPHQL_API_URL=http://localhost
13+
KADENA_GRAPHQL_API_PORT=3001
14+
API_GATEWAY_URL=http://localhost:3001
15+
API_KADENA_URL=kadena.io

indexer/src/index.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { usePostgraphile } from './server/metrics';
88
import { useKadenaGraphqlServer } from './kadena-server/server';
99
import { closeDatabase } from './config/database';
1010
import { initializeDatabase } from './config/init';
11-
import { startBackfillCoinbaseTransactions } from './services/sync/coinbase';
1211
import { backfillBalances } from './services/sync/balances';
1312
import { startMissingBlocks } from './services/sync/missing';
1413

@@ -44,8 +43,6 @@ async function main() {
4443
await backfillBalances();
4544
await closeDatabase();
4645
process.exit(0);
47-
} else if (options.coinbase) {
48-
await startBackfillCoinbaseTransactions();
4946
} else if (options.missing) {
5047
await startMissingBlocks();
5148
process.exit(0);

indexer/src/services/sync/coinbase.ts

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,6 @@ import { Transaction } from 'sequelize';
55
import Event, { EventAttributes } from '../../models/event';
66
import { getCoinTransfers } from './transfers';
77

8-
export async function startBackfillCoinbaseTransactions() {
9-
console.log('Starting coinbase backfill ...');
10-
11-
const limit = 1000; // Number of rows to process in one batch
12-
let offset = 0;
13-
14-
while (true) {
15-
console.log(`Fetching rows from offset: ${offset}, limit: ${limit}`);
16-
const res = await rootPgPool.query(
17-
`SELECT b.id, b.coinbase, b."chainId", b."creationTime" FROM "Blocks" b ORDER BY b.id LIMIT $1 OFFSET $2`,
18-
[limit, offset],
19-
);
20-
21-
const rows = res.rows;
22-
if (rows.length === 0) {
23-
console.log('No more rows to process.');
24-
break;
25-
}
26-
27-
const tx = await sequelize.transaction();
28-
try {
29-
await addCoinbaseTransactions(rows, tx);
30-
await tx.commit();
31-
console.log(`Batch at offset ${offset} processed successfully.`);
32-
offset += limit;
33-
} catch (batchError) {
34-
console.error(`Error processing batch at offset ${offset}:`, batchError);
35-
try {
36-
await tx.rollback();
37-
console.log(`Transaction for batch at offset ${offset} rolled back.`);
38-
} catch (rollbackError) {
39-
console.error('Error during rollback:', rollbackError);
40-
}
41-
break;
42-
}
43-
}
44-
45-
await closeDatabase();
46-
process.exit(0);
47-
}
48-
498
export async function addCoinbaseTransactions(
509
rows: Array<any>,
5110
tx: Transaction,

indexer/src/utils/helpers.ts

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,6 @@ export function delay(ms: number): Promise<void> {
2424
return new Promise(resolve => setTimeout(resolve, ms));
2525
}
2626

27-
/**
28-
* Splits a range into smaller chunks based on a specified size.
29-
* This function is useful for breaking down a large range of numbers into manageable parts,
30-
* for example, when processing data in batches.
31-
*
32-
* @param min The minimum value of the range to split.
33-
* @param max The maximum value of the range to split.
34-
* @param rangeSize The size of each chunk.
35-
* @returns An array of arrays, where each inner array represents a chunk with a start and end value.
36-
*/
37-
export function splitIntoChunks(min: number, max: number, rangeSize: number): number[][] {
38-
const chunks = [];
39-
let current = max;
40-
if (max - min <= rangeSize) {
41-
return [[min, max]];
42-
}
43-
while (current > min) {
44-
const next = Math.max(current - rangeSize, min);
45-
chunks.push([next, current]);
46-
current = next - 1;
47-
}
48-
return chunks;
49-
}
50-
51-
/**
52-
* Calculates the size of a data object in bytes.
53-
*
54-
* @param data The data object to size.
55-
* @returns The size of the data in bytes.
56-
*/
57-
export function calculateDataSize(data: any) {
58-
return Buffer.byteLength(JSON.stringify(data), 'utf8');
59-
}
60-
6127
/**
6228
* Retrieves a required environment variable as a string.
6329
* Throws an error if the variable is not found, ensuring that the application configuration is correctly defined.
@@ -73,46 +39,3 @@ export function getRequiredEnvString(key: string): string {
7339
}
7440
return value;
7541
}
76-
77-
/**
78-
* Retrieves a required environment variable as a number.
79-
* Parses the variable value as an integer and throws an error if the variable is not found or if it cannot be parsed as a number.
80-
* This ensures that numeric environment configurations are valid and available before proceeding.
81-
*
82-
* @param key - The name of the environment variable to retrieve and parse as a number.
83-
* @returns The parsed value of the environment variable as a number.
84-
* @throws {Error} If the environment variable is not set or cannot be parsed as a valid number.
85-
*/
86-
export function getRequiredEnvNumber(key: string): number {
87-
const value = process.env[key];
88-
if (!value) {
89-
throw new Error(`Environment variable ${key} is required`);
90-
}
91-
const parsed = parseInt(value, 10);
92-
if (isNaN(parsed)) {
93-
throw new Error(`Environment variable ${key} must be a valid number`);
94-
}
95-
return parsed;
96-
}
97-
98-
/**
99-
* Creates a signal object that can be used to manage shutdown or interrupt signals in asynchronous operations.
100-
* It provides a mechanism to gracefully exit from a loop or terminate a process when an external signal is received.
101-
* The signal object contains a boolean flag that is initially set to false and can be toggled to true using the
102-
* trigger method. This flag can be checked periodically in asynchronous loops to determine if the process should
103-
* continue running or begin shutdown procedures.
104-
*
105-
* @returns An object with properties 'isTriggered' to check the current state of the signal,
106-
* and 'trigger' to change the state to triggered, indicating that a shutdown or interrupt has been requested.
107-
*/
108-
export function createSignal() {
109-
let isTriggered = false;
110-
return {
111-
get isTriggered() {
112-
return isTriggered;
113-
},
114-
trigger() {
115-
isTriggered = true;
116-
},
117-
};
118-
}

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@
2121
"run-indexer-workflow": "act -W .github/workflows/indexer.yml --secret-file ./indexer/.env",
2222
"format": "prettier --write \"**/*.{yml,yaml,json,md,js,ts}\"",
2323
"format:check": "prettier --check \"**/*.{yml,yaml,json,md,js,ts}\"",
24-
"prepare": "husky"
24+
"prepare": "husky",
25+
"docker:login": "aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 325501467038.dkr.ecr.us-east-1.amazonaws.com",
26+
"deploy:missing": "sh deploy.sh missing",
27+
"deploy:streaming": "sh deploy.sh streaming",
28+
"deploy:graphql": "sh deploy.sh graphql"
2529
},
2630
"dependencies": {},
2731
"devDependencies": {

0 commit comments

Comments
 (0)