Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ElectronPlatform: Add support for a event index using Seshat. #11125

Merged
merged 32 commits into from
Nov 26, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1dbdd0a
ElectronPlatform: Add support for a event index using Seshat.
poljar Oct 11, 2019
71023ae
ElectronPlatform: Fix lint errors.
poljar Oct 11, 2019
94196eb
electron-main: Use camle-case for the send_error method.
poljar Nov 8, 2019
a6839af
electron-main: Use a capital letter for the seshat import.
poljar Nov 8, 2019
c3c5756
ElectronPlatform: Implement the EventIndexManager for Seshat.
poljar Nov 13, 2019
449eca6
electron-main: Add a missing break.
poljar Nov 13, 2019
437c59f
electron-main: Check for seshat existence instead of erroring out.
poljar Nov 13, 2019
e9352fc
electron-main: Switch to matrix-seshat.
poljar Nov 14, 2019
b90a94b
electron-main: Enable encryption for Seshat.
poljar Nov 14, 2019
7147af8
ElectronPlatform: Don't scope the event index per user.
poljar Nov 14, 2019
dd2c210
electron-main: Rework the event index initialization and deletion.
poljar Nov 14, 2019
076bf6f
develop: Enable the event indexing feature in labs.
poljar Nov 19, 2019
0813aff
electron-main: Remove an extra newline.
poljar Nov 19, 2019
b17a403
electron-main: No need to normalize the path.
poljar Nov 19, 2019
4a25252
ElectronPlatform: Rename the SeshatIndexerManager.
poljar Nov 19, 2019
73b302f
ElectronPlatform: Fix some type annotations.
poljar Nov 19, 2019
137bedb
ElectronPlatform: Update the path for the BaseEventIndexManager class.
poljar Nov 19, 2019
2f2cbad
electron_app: Remove Seshat from the dependencies.
poljar Nov 21, 2019
d0b5391
docs: Add documentation explaining how to enable Seshat support.
poljar Nov 21, 2019
e96c44c
package.json: Remove the unneeded Neon/Seshat dependencies.
poljar Nov 26, 2019
4c629e8
native-node-modules: Add a header level to the title.
poljar Nov 26, 2019
da4b403
native-node-modules: Don't mention the riot version that supports nat…
poljar Nov 26, 2019
b52141d
native-node-modules: Add a section about cross compilation.
poljar Nov 26, 2019
5f6636e
native-node-modules: Reword the second paragraph.
poljar Nov 26, 2019
b1aff29
native-node-modules: Explain the packaging situation a bit.
poljar Nov 26, 2019
40f2648
native-node-modules: Expand the Seshat subtitle a bit.
poljar Nov 26, 2019
f0fe968
native-node-modules: Capitalize some project names.
poljar Nov 26, 2019
5b8e918
native-node-modules: Explain how to install Rust and link to its docs.
poljar Nov 26, 2019
1869350
native-node-modules: Remove a spurious and.
poljar Nov 26, 2019
b0783a8
native-node-modules: Mention that Seshat requires SQLCipher.
poljar Nov 26, 2019
f28f27a
labs: Document the event indexing labs feature.
poljar Nov 26, 2019
e5956de
labs: Clarify that the event indexing feature supports E2EE search.
poljar Nov 26, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion electron_app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
"version": "1.4.2",
"description": "A feature-rich client for Matrix.org",
"author": "New Vector Ltd.",
"scripts": {
"build": "electron-build-env --electron 6.0.3 neon build seshat-node --release",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should really try hard to find a way to build that doesn't duplicate the Electron version in another place, as we'll surely forget to keep them synchronised. Maybe we need a wrapper script to pull it out of the main package.json?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing doesn't even work with the version passed as is. It seems to be only necessary if you need to rebuild seshat for some reason (e.g. if you're linking it from your dev folder) anyways.

Since we're adding run-time checks for seshat anyways it will be safe to remove it as well.

"postinstall": "yarn build"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, so this is just to call the line above...?

},
"dependencies": {
"auto-launch": "^5.0.1",
"electron-store": "^2.0.0",
"electron-window-state": "^4.1.0",
"minimist": "^1.2.0",
"png-to-ico": "^1.0.2"
"png-to-ico": "^1.0.2",
"make-dir": "^3.0.0",
"seshat-node": "^0.2.0"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be quite nice to have this renamed to something without the redundant node instead. See matrix-org/seshat#9.

}
}
116 changes: 116 additions & 0 deletions electron_app/src/electron-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const { migrateFromOldOrigin } = require('./originMigrator');

const windowStateKeeper = require('electron-window-state');
const Store = require('electron-store');
const seshat = require('seshat-node');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As part of attempting to land this without a path to build it, let's test at runtime for its existence with a try / catch.

const makeDir = require('make-dir');

if (argv["help"]) {
console.log("Options:");
Expand Down Expand Up @@ -82,8 +84,12 @@ try {
// Could not load local config, this is expected in most cases.
}


jryans marked this conversation as resolved.
Show resolved Hide resolved
const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
const store = new Store({ name: "electron-config" });

let eventIndex = null;

let mainWindow = null;
global.appQuitting = false;
global.minimizeToTray = store.get('minimizeToTray', true);
Expand Down Expand Up @@ -149,6 +155,17 @@ autoUpdater.on('update-downloaded', (ev, releaseNotes, releaseName, releaseDate,
ipcMain.on('ipcCall', async function(ev, payload) {
if (!mainWindow) return;

const send_error = (id, e) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use camel-case naming:

Suggested change
const send_error = (id, e) => {
const sendError = (id, e) => {

(We should have linting rules for this, but they seem not to have fired here... 🤔)

const error = {
message: e.message
}

mainWindow.webContents.send('ipcReply', {
id:id,
error: error
});
}

const args = payload.args || [];
let ret;

Expand Down Expand Up @@ -200,6 +217,105 @@ ipcMain.on('ipcCall', async function(ev, payload) {
case 'getConfig':
ret = vectorConfig;
break;

case 'initEventIndex':
if (args[0] && eventIndex === null) {
let p = path.normalize(path.join(eventStorePath, args[0]));
try {
await makeDir(p);
eventIndex = new seshat(p);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A common JS convention is for new-able things to start with a capital letter. I suppose we may not have a linting rule enforcing that at the moment, but I suggest changing the require to call it Seshat instead, unless there's a strong reason to always use the lowercase name.

console.log("Initialized event store");
} catch (e) {
send_error(payload.id, e);
return;
}
}
break;

case 'deleteEventIndex':
await eventIndex.delete();
eventIndex = null;

case 'isEventIndexEmpty':
if (eventIndex === null) ret = true;
else ret = await eventIndex.isEmpty();
break;

case 'addEventToIndex':
try {
eventIndex.addEvent(args[0], args[1]);
} catch (e) {
send_error(payload.id, e);
return;
}
break;

case 'commitLiveEvents':
try {
ret = await eventIndex.commit();
} catch (e) {
send_error(payload.id, e);
return;
}
break;

case 'searchEventIndex':
try {
ret = await eventIndex.search(args[0]);
} catch (e) {
send_error(payload.id, e);
return;
}
break;

case 'addHistoricEvents':
if (eventIndex === null) ret = false;
else {
try {
ret = await eventIndex.addHistoricEvents(
args[0], args[1], args[2]);
} catch (e) {
send_error(payload.id, e);
return;
}
}
break;

case 'removeCrawlerCheckpoint':
if (eventIndex === null) ret = false;
else {
try {
ret = await eventIndex.removeCrawlerCheckpoint(args[0]);
} catch (e) {
send_error(payload.id, e);
return;
}
}
break;

case 'addCrawlerCheckpoint':
if (eventIndex === null) ret = false;
else {
try {
ret = await eventIndex.addCrawlerCheckpoint(args[0]);
} catch (e) {
send_error(payload.id, e);
return;
}
}
break;

case 'loadCheckpoints':
if (eventIndex === null) ret = [];
else {
try {
ret = await eventIndex.loadCheckpoints();
} catch (e) {
ret = [];
}
}
break;

default:
mainWindow.webContents.send('ipcReply', {
id: payload.id,
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@
"source-map-loader": "^0.2.4",
"webpack": "^4.23.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.11"
"webpack-dev-server": "^3.1.11",
"electron-build-env": "^0.2.0",
jryans marked this conversation as resolved.
Show resolved Hide resolved
"neon-cli": "^0.3.1"
},
"build": {
"appId": "im.riot.app",
Expand Down
44 changes: 44 additions & 0 deletions src/vector/platform/ElectronPlatform.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,48 @@ export default class ElectronPlatform extends VectorBasePlatform {
callbacks.resolve(payload.reply);
}
}

async initEventIndex(userId: string): void {
return this._ipcCall('initEventIndex', userId);
}

supportsEventIndexing(): boolean {
return true;
}

async addEventToIndex(ev: {}, profile: {}): void {
return this._ipcCall('addEventToIndex', ev, profile);
}

async isEventIndexEmpty(): Promise<boolean> {
return this._ipcCall('isEventIndexEmpty');
}

async commitLiveEvents(): Promise<{}> {
return this._ipcCall('commitLiveEvents');
}

async searchEventIndex(term: string): Promise<{}> {
return this._ipcCall('searchEventIndex', term);
}

async addHistoricEvents(events: string, checkpoint: {} = null, oldCheckpoint: {} = null): Promise<{}> {
return this._ipcCall('addHistoricEvents', events, checkpoint, oldCheckpoint);
}

async addCrawlerCheckpoint(checkpoint: {}): Promise<{}> {
return this._ipcCall('addCrawlerCheckpoint', checkpoint);
}

async removeCrawlerCheckpoint(checkpoint: {}): Promise<{}> {
return this._ipcCall('removeCrawlerCheckpoint', checkpoint);
}

async loadCheckpoints(checkpoint: {}): Promise<[{}]> {
return this._ipcCall('loadCheckpoints');
}

async deleteEventIndex(): Promise<> {
return this._ipcCall('deleteEventIndex');
}
}