yoursunny / NDNts

NDN libraries for the Modern Web
https://ndnts-docs.ndn.today
ISC License
31 stars 9 forks source link

Run PSync Partial Publisher interop-test #4

Closed tanim-ics closed 3 years ago

tanim-ics commented 3 years ago

I am trying to run psync-partial-publisher.ts from NDNts directory as you have mentioned.

NDNTS_NFDREG=1 npm run literate packages/sync/interop-test/psync-partial-publisher.ts

but I am getting the following errors:


npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /Users/XXX/Desktop/ndntts/package.json
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/Users/XXX/Desktop/ndntts/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/XXX/.npm/_logs/2021-08-16T14_16_17_807Z-debug.log
XXX@XXX-MBP ndntts % cd NDNts
XXX@XXX-MBP NDNts % NDNTS_NFDREG=1 npm run literate packages/sync/interop-test/psync-partial-publisher.ts

> @ndn/root@ literate /Users/XXX/Desktop/ndntts/NDNts
> bash mk/literate.sh "packages/sync/interop-test/psync-partial-publisher.ts"

\e[96mRUNNING packages/sync/interop-test/psync-partial-publisher.ts\e[39m
(node:3013) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@k-foss/ts-esnode' imported from /Users/XXX/Desktop/ndntts/NDNts/packages/sync/interop-test/
    at packageResolve (internal/modules/esm/resolve.js:664:9)
    at moduleResolve (internal/modules/esm/resolve.js:705:18)
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:819:11)
    at Loader.resolve (internal/modules/esm/loader.js:89:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
    at Loader.import (internal/modules/esm/loader.js:177:28)
    at internal/process/esm_loader.js:57:31
    at initializeLoader (internal/process/esm_loader.js:62:5)
    at Object.loadESM (internal/process/esm_loader.js:67:11)
    at runMainESM (internal/modules/run_main.js:47:31) {
  code: 'ERR_MODULE_NOT_FOUND'
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ndn/root@ literate: `bash mk/literate.sh "packages/sync/interop-test/psync-partial-publisher.ts"`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ndn/root@ literate script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/XXX/.npm/_logs/2021-08-16T14_16_27_308Z-debug.log

Same thing is happening for partial consumer also.
yoursunny commented 3 years ago

Did you run npm run bootstrap from the codebase checkout, so that the dependencies are installed? Did it complete successfully? (if unsure, run it again)

tanim-ics commented 3 years ago

No, I did not run before. I have run it and the dependencies are installed. But still the typescript file is not running. I have executed the following from the NDNts directory:

NDNTS_NFDREG=1 npm run literate packages/sync/interop-test/psync-partial-publisher.ts

and got the following error

> @ndn/root@ literate /Users/XXX/Desktop/ndntts/NDNts
> bash mk/literate.sh "packages/sync/interop-test/psync-partial-publisher.ts"

\e[96mRUNNING packages/sync/interop-test/psync-partial-publisher.ts\e[39m
(node:3428) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3428) Warning: The dynamicInstantiate loader hook has been removed.
internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/XXX/Desktop/ndntts/NDNts/packages/cli-common/lib/mod_node.js' imported from /Users/XXX/Desktop/ndntts/NDNts/packages/sync/interop-test/psync-partial-publisher.ts
    at finalizeResolution (internal/modules/esm/resolve.js:274:11)
    at moduleResolve (internal/modules/esm/resolve.js:708:10)
    at defaultResolve (internal/modules/esm/resolve.js:819:11)
    at resolve (file:///Users/XXX/Desktop/ndntts/NDNts/node_modules/.pnpm/@k-foss+ts-esnode@2.0.2_typescript@4.3.5/node_modules/@k-foss/ts-esnode/out/dist/index.js:53:12)
    at Loader.resolve (internal/modules/esm/loader.js:89:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
    at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:73:40)
    at link (internal/modules/esm/module_job.js:72:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ndn/root@ literate: `bash mk/literate.sh "packages/sync/interop-test/psync-partial-publisher.ts"`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ndn/root@ literate script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/XXX/.npm/_logs/2021-08-16T15_20_51_336Z-debug.log
XXX@XXX-MBP NDNts % npm run bootstrap

> @ndn/root@ bootstrap /Users/XXX/Desktop/ndntts/NDNts
> npx pnpm install && bash mk/bootstrap.sh

Scope: all 34 workspace projects
 WARN  There are cyclic workspace dependencies
Lockfile is up-to-date, resolution step is skipped
Already up-to-date
Cannot link binary 'jest' of 'jest-cli' to '/Users/XXX/Desktop/ndntts/NDNts/node_modules/.bin': binary of 'jest' is already linked
yoursunny commented 3 years ago

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/XXX/Desktop/ndntts/NDNts/packages/cli-common/lib/mod_node.js' imported from /Users/XXX/Desktop/ndntts/NDNts/packages/sync/interop-test/psync-partial-publisher.ts

You also need to run npm run build to build TypeScript (packages/*/src) into JavaScript (packages/*/lib). I haven't written these instructions, because the interop-test is intended for use during development and not as applications.

tanim-ics commented 3 years ago

It is working now after executing npm run build.

> @ndn/root@ literate /Users/tanimrayhan/Desktop/ndntts/NDNts
> bash mk/literate.sh "packages/sync/interop-test/psync-partial-publisher.ts"

\e[96mRUNNING packages/sync/interop-test/psync-partial-publisher.ts\e[39m
(node:4711) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:4711) Warning: The dynamicInstantiate loader hook has been removed.
PUBLISH /8=psync-NDNts/8=1629130538666/8=8 1
PUBLISH /8=psync-NDNts/8=1629130538666/8=11 1
PUBLISH /8=psync-NDNts/8=1629130538666/8=11 2
PUBLISH /8=psync-NDNts/8=1629130538666/8=13 1
PUBLISH /8=psync-NDNts/8=1629130538666/8=4 1

But how to run a consumer or a subscriber. In the interop-test directory Readmd file you have written the following instruction:

export NDN_LOG=examples.PartialSyncConsumerApp=INFO
LD_LIBRARY_PATH=build ./build/examples/psync-consumer /psync-interop 5

after executing the commands from the psync directory, it throws errors that there are no such files or directory.

yoursunny commented 3 years ago

after executing the commands from the psync directory, it throws errors that there are no such files or directory.

If you want to verify interoperability with PSync C++ library, you need to build PSync C++ library with examples. See instructions in PSync/examples/README.md.

If you just want to see NDNts PSync implementation in action, use the command in "PSyncPartialSubscriber" section.

tanim-ics commented 3 years ago

Both Psync partial publisher and subscriber are working. Thank you for your patience and guidance.

tanim-ics commented 3 years ago

I have run into another problem. I have written a javascript which contains both producer and publisher. But when I run it is throwing syntax error like the following:

    const nodes: Array<SyncNode<Name>> = [];
          ^^^^^

SyntaxError: Missing initializer in const declaration
    at Loader.moduleStrategy (internal/modules/esm/translators.js:145:18)
    at async link (internal/modules/esm/module_job.js:64:21)

I am sharing the code:

import { openUplinks } from "@ndn/cli-common";
import { Endpoint } from "@ndn/endpoint";
import { Name, Data } from "@ndn/packet";
import {makePSyncCompatParam, PSyncPartialPublisher, PSyncZlib, SyncNode} from "@ndn/sync";

const syncPrefix = new Name("/sync1");
const ownPrefix = new Name(`/text2lines/`);

(async () => {
    // openUplinks() creates a connection to the "uplink", in this case the local NFD forwarder.
    // It returns a Promise, so remember to await it.
    await openUplinks();

    const sync = new PSyncPartialPublisher({
        p: makePSyncCompatParam({
            ibltCompression: PSyncZlib,
        }),
        syncPrefix,
    });

    if (process.env.NDNTS_SYNC_DEBUG === "1") {
        sync.on("debug", ({ action, interestName }) => {
            console.log(`DEBUG ${action} ${interestName ?? ""}`);
        });
    }

    const nodes: Array<SyncNode<Name>> = [];
    for (let i = 0; i < 16; ++i) {
        nodes.push(sync.add(ownPrefix.append(`${i}`)));
    }

    setInterval(() => {
        const node = nodes[Math.floor(nodes.length * Math.random())];
        node.seqNum++;
        console.log(`PUBLISH ${node.id} ${node.seqNum}`);
    }, 2000);

// Endpoint is a centerpiece of NDNts. You can use it to create a producer or a consumer.
    // It is similar to, but more powerful than, "face" in other NDN libraries.
    // You'll soon see some of its powers.
    const endpoint = new Endpoint();

    // endpoint.produce() creates a producer.
    // The first argument is the name prefix.
    // The second argument is a callback function that is invoked for each incoming Interest;
    // this must be an async function that returns a Promise.
    endpoint.produce(new Name(ownPrefix), async (interest) => {
            console.log(`Got Interest ${interest.name}`);
            // This producer is a calculator. It expects Interest name to have three
            // components: "add", x, and y. If it's not, reject the Interest.
            if (interest.name.length !== 3) {
                console.log("Wrong name length.");
                return;
            }

            // Extract x and y numbers, then compute the sum.
            const x = Number.parseInt(interest.name.at(1).text);
            const y = Number.parseInt(interest.name.at(2).text);
            const sum = x + y;
            console.log(`${x} + ${y} = ${sum}`);

            // Make a Data packet that has the same name as the Interest.
            const data = new Data(interest.name);
            data.freshnessPeriod = 1000;
            data.content = new TextEncoder().encode(`${sum}\n`);

            // Sending the Data is as simple as returning it from the function.
            return data;
        },
        // options
    );
})();

it contains the producer and publisher of NDNts. I have created a javascript file named producer and I am running the file using as follows:

node producer.mjs
yoursunny commented 3 years ago

const nodes: Array<SyncNode> = [];

You are writing TypeScript.

node producer.mjs

You are running it as JavaScript, so you get syntax error.

You should do one of the following:

tanim-ics commented 3 years ago

I am using nightly-build modules. Only this line const nodes: Array<SyncNode<Name>> = []; is throwing error. When I am trying to declare an empty array in javascript using SyncNode interface it is throwing error. Can you please help me in this regard? I am new to javascript.

yoursunny commented 3 years ago

I am new to javascript.

https://www.typescriptlang.org/docs/handbook/typescript-from-scratch.html https://developer.mozilla.org/en-US/docs/Learn/JavaScript

tanim-ics commented 3 years ago

Thank You. I was following these tutorials.

I am facing another issue. I am using your nightly-build modules. I am writing a typescript file called Psync.ts. It is same as psync-partial-publisher which you referred me above from the interop-test. This is the following code:

import { openUplinks } from "@ndn/cli-common";
import { Name } from "@ndn/packet";
import { makePSyncCompatParam, PSyncPartialPublisher, PSyncZlib, SyncNode } from "@ndn/sync";

const syncPrefix = new Name("/psync-interop");
const ownPrefix = new Name(`/psync-NDNts/${Date.now()}`);

(async () => {
    await openUplinks();

    const sync = new PSyncPartialPublisher({
        p: makePSyncCompatParam({
            ibltCompression: PSyncZlib,
        }),
        syncPrefix,
    });
    if (process.env.NDNTS_SYNC_DEBUG === "1") {
        sync.on("debug", ({ action, interestName }) => {
            console.log(`DEBUG ${action} ${interestName ?? ""}`);
        });
    }

    const nodes: Array<SyncNode<Name>> = [];
    for (let i = 0; i < 16; ++i) {
        nodes.push(sync.add(ownPrefix.append(`${i}`)));
    }

    setInterval(() => {
        const node = nodes[Math.floor(nodes.length * Math.random())];
        node.seqNum++;
        console.log(`PUBLISH ${node.id} ${node.seqNum}`);
    }, 2000);
})().catch(console.error);

I am trying to compile this code as tsc Psync.ts

but it is throwing me the following error:


2 import pushable from "it-pushable";
         ~~~~~~~~

  node_modules/it-pushable/index.d.ts:26:1
    26 export = pushable
       ~~~~~~~~~~~~~~~~~
    This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.

node_modules/@ndn/fw/lib/tap-face.d.ts:1:8 - error TS1259: Module '"/Users/XXX/Desktop/NDNts/node_modules/it-pushable/index"' can only be default-imported using the 'esModuleInterop' flag

1 import pushable from "it-pushable";
         ~~~~~~~~

  node_modules/it-pushable/index.d.ts:26:1
    26 export = pushable
       ~~~~~~~~~~~~~~~~~
    This module is declared with using 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.

Found 2 errors.

In the tsconfig.json file "esModuleInterop": true, --- this flag is true also.

Can you please give me any suggestions about this issue?

yoursunny commented 3 years ago

Please provide full content of tsconfig.json and package.json.

tanim-ics commented 3 years ago

package.json is the following:

{
  "private": true,
  "type": "module",
  "dependencies": {
    "@ndn/cli-common": "https://ndnts-nightly.ndn.today/cli-common.tgz",
    "@ndn/endpoint": "https://ndnts-nightly.ndn.today/endpoint.tgz",
    "@ndn/packet": "https://ndnts-nightly.ndn.today/packet.tgz",
    "@ndn/repo-cli": "https://ndnts-nightly.ndn.today/repo-cli.tgz",
    "@ndn/sync": "https://ndnts-nightly.ndn.today/sync.tgz",
    "@types/es6-promise": "^3.3.0"
  },
  "devDependencies": {
    "@types/node": "^16.6.1",
    "ts-node": "^10.2.1",
    "typescript": "^4.3.5"
  }
}

and tsconfig.json:

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    // "lib": [],                             /* Specify library files to be included in the compilation. */
    // "allowJs": true,                       /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    // "outDir": "./",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "composite": true,                     /* Enable project compilation */
    // "removeComments": true,                /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true,                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */

    /* Source Map Options */
    // "sourceRoot": "./",                    /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "./",                       /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
  }
}
yoursunny commented 3 years ago

I am trying to compile this code as tsc Psync.ts

I found out what's wrong: if you run tsc with a specific input file, it won't load tsconfig.json. https://stackoverflow.com/a/67619647/3729203

To solve this problem, you should run this instead:

tsc -b

This would build all input files and consider tsconfig.json settings.


You should have these in tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ES2020",
    "moduleResolution": "Node",
    "strict": true,
    "esModuleInterop": true
  }
}

It isn't possible to run NDNts in ES5 environment, because NDNts uses ES6 features such as Proxy and BigInt extensively. Therefore, building to ES5 is just unnecessary overhead.

tanim-ics commented 3 years ago

To solve this problem, you should run this instead:

tsc -b

This solution did not work for me. But instead, if I use this command

node --loader ts-node/esm ./Psync.ts

then it works.

(node:25049) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
PUBLISH /8=psync-NDNts/8=1630102854155/8=9 1
PUBLISH /8=psync-NDNts/8=1630102854155/8=14 1
PUBLISH /8=psync-NDNts/8=1630102854155/8=1 1
PUBLISH /8=psync-NDNts/8=1630102854155/8=3 1
PUBLISH /8=psync-NDNts/8=1630102854155/8=9 2

I have got this solution from this: https://stackoverflow.com/a/66626333/10033770

But I did not fully understand what is happening. It would be great if you could explain with some simple words.

yoursunny commented 3 years ago
tsc -b

This solution did not work for me.

What's the error message?


One possible issue is that tsc refers to a different TypeScript command, such as one installed via npm install -g or apt. If this is the problem, the following two commands would give different outputs:

tsc --version
./node_modules/.bin/tsc --version

The solution is using ./node_modules/.bin/tsc instead of tsc, so that it always refers to the local version.

tanim-ics commented 3 years ago
tsc -b

This solution did not work for me.

What's the error message?

Same error as before. esModueInterop flag error.

One possible issue is that tsc refers to a different TypeScript command, such as one installed via npm install -g or apt. If this is the problem, the following two commands would give different outputs:

tsc --version
./node_modules/.bin/tsc --version

The solution is using ./node_modules/.bin/tsc instead of tsc, so that it always refers to the local version.

I got the same output of this tsc --version & ./node_modules/.bin/tsc --version

XXX@XXX-MBP NDNts % tsc --version
Version 4.3.5
XXX@XXX-MBP NDNts % ./node_modules/.bin/tsc --version
Version 4.3.5
yoursunny commented 3 years ago
tsc -b

Same error as before. esModueInterop flag error.

To confirm, are you running just tsc -b (no filename), or are you running tsc -b PSync.ts (with filename)? As https://stackoverflow.com/a/67619647/3729203 said, you cannot put filename on the command line, or tsconfig.json is completely ignored.

tanim-ics commented 3 years ago

I am running only

tsc -b

without any filename.

yoursunny commented 3 years ago

I used "tsc -b" for building. But after that how can I run a single TS file? I used "ts-node Psync.ts" to run the file.

If tsc -b has completed successfully, it should have generated a .js file that has the same name as the .ts. You can then run the .js output directly:

node PSync.js

There's no need to use ts-node.

tanim-ics commented 3 years ago

Thank you. Now it is working.

tanim-ics commented 3 years ago

I am opening the issue again because I ran into a problem where I am publishing 2 topics under the same sync prefix. The publishing is working fine. But on the subscriber side, I am not seeing the other topic. I am sharing both the code:

Heres is the psync-partial-publisher.ts code:

import { openUplinks } from "@ndn/cli-common";
import { Name } from "@ndn/packet";
import { makePSyncCompatParam, PSyncPartialPublisher, PSyncZlib, SyncNode } from "@ndn/sync";

const syncPrefix = new Name("/psync-interop");
const ownPrefix1 = new Name(`/psync-NDNts/${Date.now()}`);
const ownPrefix2 = new Name(`/psync-NDNts1/${Date.now()}`);

(async () => {
    await openUplinks();

    const sync1 = new PSyncPartialPublisher({
        p: makePSyncCompatParam({
            ibltCompression: PSyncZlib,
        }),
        // @ts-ignore
        syncPrefix,
    });

    const sync2 = new PSyncPartialPublisher({
        p: makePSyncCompatParam({
            ibltCompression: PSyncZlib,
        }),
        // @ts-ignore
        syncPrefix,
    });

    if (process.env.NDNTS_SYNC_DEBUG === "1") {
        sync1.on("debug", ({ action, interestName }) => {
            console.log(`DEBUG ${action} ${interestName ?? ""}`);
        });
    }

    const nodes: Array<SyncNode<Name>> = [];

    for (let i = 0; i < 20; ++i) {
        // @ts-ignore
        nodes.push(sync1.add(ownPrefix1.append(`${i}`)));
        // @ts-ignore
        nodes.push(sync2.add(ownPrefix2.append(`${i}`)));
    }

    setInterval(() => {
        const node = nodes[Math.floor(nodes.length * Math.random())];
        node.seqNum++;
        console.log(`PUBLISH ${node.id} ${node.seqNum}`);
    }, 2000);
})().catch(console.error);

The output of the publisher:

PUBLISH /8=psync-NDNts/8=1631553485459/8=14 1
PUBLISH /8=psync-NDNts/8=1631553485459/8=2 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=16 2
PUBLISH /8=psync-NDNts/8=1631553485459/8=14 2
PUBLISH /8=psync-NDNts/8=1631553485459/8=4 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=1 2
PUBLISH /8=psync-NDNts1/8=1631553485459/8=12 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=16 3
PUBLISH /8=psync-NDNts1/8=1631553485459/8=5 2
PUBLISH /8=psync-NDNts1/8=1631553485459/8=11 3
PUBLISH /8=psync-NDNts1/8=1631553485459/8=5 3
PUBLISH /8=psync-NDNts/8=1631553485459/8=17 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=3 1
PUBLISH /8=psync-NDNts/8=1631553485459/8=19 2
PUBLISH /8=psync-NDNts1/8=1631553485459/8=5 4
PUBLISH /8=psync-NDNts1/8=1631553485459/8=3 2
PUBLISH /8=psync-NDNts/8=1631553485459/8=6 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=9 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=6 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=16 4
PUBLISH /8=psync-NDNts1/8=1631553485459/8=16 5
PUBLISH /8=psync-NDNts1/8=1631553485459/8=7 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=16 6
PUBLISH /8=psync-NDNts1/8=1631553485459/8=9 2
PUBLISH /8=psync-NDNts/8=1631553485459/8=7 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=10 3
PUBLISH /8=psync-NDNts/8=1631553485459/8=5 2
PUBLISH /8=psync-NDNts/8=1631553485459/8=12 2
PUBLISH /8=psync-NDNts1/8=1631553485459/8=3 3
PUBLISH /8=psync-NDNts1/8=1631553485459/8=16 7
PUBLISH /8=psync-NDNts/8=1631553485459/8=8 1
PUBLISH /8=psync-NDNts1/8=1631553485459/8=10 4
PUBLISH /8=psync-NDNts/8=1631553485459/8=15 2
PUBLISH /8=psync-NDNts1/8=1631553485459/8=6 2
PUBLISH /8=psync-NDNts/8=1631553485459/8=2 2
PUBLISH /8=psync-NDNts/8=1631553485459/8=0 1
PUBLISH /8=psync-NDNts/8=1631553485459/8=9 2
PUBLISH /8=psync-NDNts1/8=1631553485459/8=3 4
PUBLISH /8=psync-NDNts1/8=1631553485459/8=14 1

this is the subscriber code:

import { openUplinks } from "@ndn/cli-common";
import { Name } from "@ndn/packet";
import { makePSyncCompatParam, PSyncPartialSubscriber, PSyncZlib, Subscription } from "@ndn/sync";
import { toHex } from "@ndn/tlv";

const syncPrefix = new Name("/psync-interop");

(async () => {
  await openUplinks();

  const sync = new PSyncPartialSubscriber({
    p: makePSyncCompatParam({
      ibltCompression: PSyncZlib,
    }),
    // @ts-ignore
    syncPrefix,
  });

  const subs = new Map<string, Subscription>();

  sync.on("state", (topics) => {
    for (const topic of topics) {
      const topicHex = toHex(topic.prefix.value);
      const shouldSubscribe = Math.random() < 0.4;
      if (topicHex) {
        let sub = subs.get(topicHex);
        if (!sub) {
          console.log(`SUBSCRIBE ${topic.prefix}`);
          sub = sync.subscribe(topic);
          subs.set(topicHex, sub);
          sub.on("update", ({ id, loSeqNum, hiSeqNum }) => {
            console.log(`UPDATE ${id} ${loSeqNum}${loSeqNum === hiSeqNum ? "" : `..${hiSeqNum}`}`);
          });
        }
      } else {
        const sub = subs.get(topicHex);
        if (sub) {
          console.log(`UNSUBSCRIBE ${topic.prefix}`);
          sub.remove();
          subs.delete(topicHex);
        }
      }
    }
  });
})().catch(console.error);

Output of the subscriber:

SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=0

SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=1
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=2
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=3
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=4
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=5
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=6
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=7
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=8
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=9
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=10
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=11
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=12
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=13
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=14
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=15
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=16
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=17
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=18
SUBSCRIBE /8=psync-NDNts/8=1631553485459/8=19
UPDATE /8=psync-NDNts/8=1631553485459/8=7 1
UPDATE /8=psync-NDNts/8=1631553485459/8=5 2
UPDATE /8=psync-NDNts/8=1631553485459/8=12 2
UPDATE /8=psync-NDNts/8=1631553485459/8=8 1
UPDATE /8=psync-NDNts/8=1631553485459/8=15 2
UPDATE /8=psync-NDNts/8=1631553485459/8=2 2
UPDATE /8=psync-NDNts/8=1631553485459/8=0 1
UPDATE /8=psync-NDNts/8=1631553485459/8=9 2

Can you please share your insights, please? It would be a great help if you can share a code snippet of multiple producers under the same sync prefix and thank you so much for your patience and guidance.

yoursunny commented 3 years ago

I am opening the issue again because I ran into a problem where I am publishing 2 topic under same sync prefix. The publishing is working fine. But on the subscriber side I am not seeing the other topic. I am sharing both the code: Can you please share your insights, please? It would be a great help if you can share a code snippet of multiple producers under the same sync prefix and thank you so much for your patience and guidance.

PSyncPartial does not support having multiple publishers on the same sync prefix, unless every publisher publishes the same dataset. I tried to do the exact same thing in PSync C++ library and it doesn't work, and then PSync designers told me that this can't be done.

See this mailing list thread: https://www.lists.cs.ucla.edu/pipermail/ndn-lib/2019-January/000460.html Follow "Next message (by thread)" link at the bottom to see replies.

tanim-ics commented 3 years ago

I understood. I read the mail thread. I have another question in that regard. Is the above scenario of having multiple publishers on the same sync prefix possible with State Vector Sync(SVS)?

yoursunny commented 3 years ago

This has to split to two questions.

Is having multiple publishers on the same sync prefix possible with State Vector Sync(SVS)?

Yes, both SVS and PSyncFull support having multiple participants on the same sync prefix. In fact, all participants must use the same sync prefix, in order to synchronize with each other.

Is the above scenario possible with State Vector Sync(SVS)?

This one is problematic: SVS and PSyncFull are group synchronization protocols; they offer a different service than PSyncPartial. PSyncPartial cannot be replaced by another protocol.

PSyncPartial: I have 500 streams; you can choose 100 of them and subscribe to these; I wouldn't bother you with my other 400 streams. SVS and PSyncFull: each of us has 1 stream; you must join us, and then you can subscribe to all the streams at once.