mirror of
https://github.com/fluencelabs/fluence-js.git
synced 2025-03-15 15:30:49 +00:00
wip
This commit is contained in:
parent
658a41b418
commit
157d6309c1
@ -22,7 +22,7 @@ import { FluenceConnection } from './FluenceConnection';
|
|||||||
import { Particle, ParticleExecutionStage, ParticleQueueItem } from './Particle';
|
import { Particle, ParticleExecutionStage, ParticleQueueItem } from './Particle';
|
||||||
import { KeyPair } from './KeyPair';
|
import { KeyPair } from './KeyPair';
|
||||||
import { dataToString, avmLogFunction, w } from './utils';
|
import { dataToString, avmLogFunction, w } from './utils';
|
||||||
import { filter, pipe, Subject, tap } from 'rxjs';
|
import { catchError, concatMap, filter, map, pipe, Subject, tap } from 'rxjs';
|
||||||
import { RequestFlow } from './compilerSupport/v1';
|
import { RequestFlow } from './compilerSupport/v1';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { defaultServices } from './defaultServices';
|
import { defaultServices } from './defaultServices';
|
||||||
@ -414,73 +414,134 @@ export class FluencePeer {
|
|||||||
let particlesQueue = new Subject<ParticleQueueItem>();
|
let particlesQueue = new Subject<ParticleQueueItem>();
|
||||||
let prevData: Uint8Array = Buffer.from([]);
|
let prevData: Uint8Array = Buffer.from([]);
|
||||||
|
|
||||||
particlesQueue
|
const interpreted = particlesQueue.pipe(
|
||||||
.pipe(
|
filterExpiredParticles(this._expireParticle.bind(this)),
|
||||||
// force new line
|
tap((item) => {
|
||||||
filterExpiredParticles(this._expireParticle.bind(this)),
|
item.particle.logTo('debug', 'Sending particle to interpreter');
|
||||||
)
|
log.debug('prevData: ', dataToString(prevData));
|
||||||
.subscribe(async (item) => {
|
}),
|
||||||
const particle = item.particle;
|
concatMap((item) =>
|
||||||
const result = await runAvmWorker(this.getStatus().peerId, this._worker, particle, prevData);
|
this._worker
|
||||||
|
.run(
|
||||||
|
item.particle.script,
|
||||||
|
prevData,
|
||||||
|
item.particle.data,
|
||||||
|
{
|
||||||
|
initPeerId: item.particle.initPeerId,
|
||||||
|
currentPeerId: this.getStatus().peerId,
|
||||||
|
},
|
||||||
|
item.particle.callResults,
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
return { ...item, interpreterResult: res };
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
tap(({ interpreterResult }) => {
|
||||||
|
const toLog: any = { ...interpreterResult };
|
||||||
|
toLog.data = dataToString(toLog.data);
|
||||||
|
|
||||||
// Do not continue if there was an error in particle interpretation
|
if (isInterpretationSuccessful(interpreterResult)) {
|
||||||
if (!isInterpretationSuccessful(result)) {
|
log.debug('Interpreter result: ', w(toLog));
|
||||||
item.onStageChange({ stage: 'interpreterError', errorMessage: result.errorMessage });
|
} else {
|
||||||
return;
|
log.error('Interpreter failed: ', w(toLog));
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
map((item) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
newData: Buffer.from(item.interpreterResult.data),
|
||||||
|
isInterpretationSuccessful: isInterpretationSuccessful(item.interpreterResult),
|
||||||
|
hasPeerPks: item.interpreterResult.nextPeerPks.length > 0,
|
||||||
|
hasCallRequests: item.interpreterResult.callRequests.length > 0,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
map((item) => {
|
||||||
|
prevData = item.newData;
|
||||||
|
return item;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
interpreted.pipe(
|
||||||
|
filter((x) => !x.isInterpretationSuccessful),
|
||||||
|
tap((item) =>
|
||||||
|
setTimeout(() => {
|
||||||
|
item.onStageChange({
|
||||||
|
stage: 'interpreterError',
|
||||||
|
errorMessage: item.interpreterResult.errorMessage,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}, 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
interpreted.pipe(
|
||||||
|
filter((x) => x.isInterpretationSuccessful),
|
||||||
|
tap((item) =>
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
item.onStageChange({ stage: 'interpreted' });
|
item.onStageChange({ stage: 'interpreted' });
|
||||||
}, 0);
|
}, 0),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
const newData = Buffer.from(result.data);
|
interpreted.pipe(
|
||||||
prevData = newData;
|
filter((x) => x.isInterpretationSuccessful),
|
||||||
|
filter((x) => x.hasPeerPks),
|
||||||
|
tap((item) => {
|
||||||
|
const newParticle = item.particle.clone();
|
||||||
|
newParticle.data = item.newData;
|
||||||
|
this._outgoingParticles.next({ ...item, particle: newParticle });
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// send particle further if requested
|
interpreted.pipe(
|
||||||
if (result.nextPeerPks.length > 0) {
|
filter((x) => x.isInterpretationSuccessful),
|
||||||
const newParticle = particle.clone();
|
filter((x) => !x.hasCallRequests),
|
||||||
newParticle.data = newData;
|
tap((item) => {
|
||||||
this._outgoingParticles.next({ ...item, particle: newParticle });
|
item.onStageChange({ stage: 'localWorkDone' });
|
||||||
}
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// execute call requests if needed
|
interpreted
|
||||||
// and put particle with the results back to queue
|
.pipe(
|
||||||
if (result.callRequests.length > 0) {
|
filter((x) => x.isInterpretationSuccessful),
|
||||||
for (let [key, cr] of result.callRequests) {
|
filter((x) => x.hasCallRequests),
|
||||||
const req = {
|
concatMap((item) => item.interpreterResult.callRequests.map(([key, cr]) => [item, key, cr] as const)),
|
||||||
fnName: cr.functionName,
|
map(([item, key, cr]) => {
|
||||||
args: cr.arguments,
|
const req = {
|
||||||
serviceId: cr.serviceId,
|
fnName: cr.functionName,
|
||||||
tetraplets: cr.tetraplets,
|
args: cr.arguments,
|
||||||
particleContext: particle.getParticleContext(),
|
serviceId: cr.serviceId,
|
||||||
};
|
tetraplets: cr.tetraplets,
|
||||||
|
particleContext: item.particle.getParticleContext(),
|
||||||
|
};
|
||||||
|
return [item, key, req] as const;
|
||||||
|
}),
|
||||||
|
concatMap(([item, key, req]) => {
|
||||||
|
return this._execSingleCallRequest(req)
|
||||||
|
.catch(
|
||||||
|
(err): CallServiceResult => ({
|
||||||
|
retCode: ResultCodes.exceptionInHandler,
|
||||||
|
result: `Handler failed. fnName="${req.fnName}" serviceId="${
|
||||||
|
req.serviceId
|
||||||
|
}" error: ${err.toString()}`,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.then((res) => [item, key, res] as const);
|
||||||
|
}),
|
||||||
|
map(([item, key, res]) => {
|
||||||
|
const serviceResult = {
|
||||||
|
result: w(res.result),
|
||||||
|
retCode: res.retCode,
|
||||||
|
};
|
||||||
|
|
||||||
this._execSingleCallRequest(req)
|
const newParticle = item.particle.clone();
|
||||||
.catch(
|
newParticle.callResults = [[key, serviceResult]];
|
||||||
(err): CallServiceResult => ({
|
newParticle.data = Buffer.from([]);
|
||||||
retCode: ResultCodes.exceptionInHandler,
|
|
||||||
result: `Handler failed. fnName="${req.fnName}" serviceId="${
|
|
||||||
req.serviceId
|
|
||||||
}" error: ${err.toString()}`,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
const serviceResult = {
|
|
||||||
result: w(res.result),
|
|
||||||
retCode: res.retCode,
|
|
||||||
};
|
|
||||||
|
|
||||||
const newParticle = particle.clone();
|
return { particle: newParticle, onStageChange: item.onStageChange };
|
||||||
newParticle.callResults = [[key, serviceResult]];
|
}),
|
||||||
newParticle.data = Buffer.from([]);
|
)
|
||||||
|
.subscribe((item) => particlesQueue.next(item));
|
||||||
particlesQueue.next({ ...item, particle: newParticle });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.onStageChange({ stage: 'localWorkDone' });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return particlesQueue;
|
return particlesQueue;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user