blob: 0879e423a60109251269a1d013c794f5d9e3b733 [file]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { open } from 'node:fs/promises';
import { resolve } from 'node:path';
import { pipeline } from 'node:stream/promises';
import { Writable, type TransformCallback } from 'node:stream';
import { HeaderValue } from '../index.js';
import { getClient } from './utils.js';
export const fileToTopic = async (
filepath: string,
streamId: number,
topicId: number,
highWaterMark = 512 * 1024
) => {
const cli = getClient();
await cli.stream.ensure(streamId);
await cli.topic.ensure(streamId, topicId);
const fd = await open(filepath);
const fname = filepath.split('/').pop() || filepath;
const st = await fd.stat();
console.log('FILE/STAT', fname, '~', (st.size / (1024 * 1024)).toFixed(2), 'mb', st);
const dStart = Date.now();
try {
let idx = 0;
await pipeline(
fd.createReadStream({highWaterMark}),
new Writable({
async write(chunks: Buffer, encoding: BufferEncoding, cb: TransformCallback) {
const messages = [{
headers: {
fileindex: HeaderValue.Uint32(idx++),
filename: HeaderValue.String(fname)
},
payload: chunks
}];
try {
await cli.message.send({ streamId, topicId, messages });
cb();
} catch (err) {
console.log('WRITE ERR', err, chunks);
cb(err as Error);
}
}
})
);
console.log(`Finished ! took ${Date.now() - dStart}ms`,);
} catch (err) {
console.error('Pipeline failed !', err);
throw err;
}
};
const argz = process.argv.slice(2);
const [rPath, streamIdStr, topicIdStr] = argz;
if (argz.length < 3 || ['-h', '--help', '?'].includes(argz[0])) {
console.log(`Usage: node stream-file-to-topic.js filePath streamId topicId`)
console.log('got', argz);
console.log('note: this script only accept numerical stream/topic id');
process.exit(1);
}
const filepath = resolve(rPath);
const streamId = parseInt(streamIdStr);
const topicId = parseInt(topicIdStr);
console.log('running with params:', { filepath, streamId, topicId })
try {
await fileToTopic(filepath, streamId, topicId, 512 * 1024);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch(err) {
process.exit(1);
}
process.exit(0);