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

Electron hangs while using realm.write() #2434

Closed
jindalrohit opened this issue Jul 4, 2019 · 14 comments
Closed

Electron hangs while using realm.write() #2434

jindalrohit opened this issue Jul 4, 2019 · 14 comments

Comments

@jindalrohit
Copy link

jindalrohit commented Jul 4, 2019

I am using realm with Electron and adding the record in the db but application hangs after inserting the record. No error is displayed.

Electron : v4.1.4
Realm : v3.0.0-beta.1
Node.js : v10.15.1

Below is the code :

const PersonSchema = {
name: 'Person',
properties: {
firstName: 'string',
lastName: 'string',
fullName: 'string'
}
};

const config = {
path: 'C:\Users\user01\AppData\Roaming\invoice\database.realm',
schema: [PersonSchema]

};

Realm.open(config).then(function (realm) {
try {
realm.write(() => {
const john = realm.create('Person', {
firstName: 'first',
lastName: 'last',
fullName: 'first last'
}, Realm.UpdateMode.Never);
});
} catch (e) {
console.log("Error on creation : ", e);
}

}, function (error) {
console.log(error);
});

@kneth
Copy link
Contributor

kneth commented Jul 5, 2019

First, you don't need the try/catch block as Realm.write()will handle any errors in the transaction.

Second, you need to resolve the promise.

@jindalrohit
Copy link
Author

jindalrohit commented Jul 12, 2019

@kneth : After using promise still write() is hanging the application

In database.js file

function insertNew(schemaName, data, mode = Realm.UpdateMode.Never) {
	return new Promise(function (resolve, reject) {
		Realm.open(databaseConfig).then(function (realm) {
			realm.write(function () {
				const response = realm.create(schemaName, data, mode);
				resolve(response);
			});
		}).catch(function (error) {
			reject(error);
		});
	});
}

module.exports = {
	insertNew: insertNew
}

//In Customer.js file

var database = require(. / database);

function insertCustomer(event, args) {
	const schemaName = arg.collection;
	const data = arg.data;
	dataBase.insertNew(schemaName, data, Realm.UpdateMode.Never).then(function (response) {
		console.log('enter in the response', response);
		event.sender.send('Database-Customer-Save', {
			response: response
		});
	}, function (err) {
		console.log('erere', err);
	});
}

@kneth
Copy link
Contributor

kneth commented Jul 12, 2019

@jindalrohit Try to move resolve() outside write().

@jindalrohit
Copy link
Author

@kneth But that will not resolve my purpose. Ideally, we must call resolve after the statements are executed.

I am developing application using Electron, Angular 8 and Realm-js. There is separation b/w front-end and back-end part. Front-end and back-end are communicating using events i.e. electron.ipcRenderer.send (in frontend) & event.sender.send (in back-end). Yesterday following code worked 3-4 times and after that it started hang the application.

Is it happening due to opening a database connection for each request? Kindly review the code.

Following is the code snippet.

In invoice.js

//  This will handle the insert event and this event is called from front-end
ipcMain.on('Database-Invoice-Insert-Request', requireArgParams(insertInvoice, ['collection', 'data']));

function insertInvoice(event, arg) {
  const schemaName = arg.collection;
  const data = arg.data;
  Realm.open(databaseConfig).then(realm => {
    const invoiceList = realm.objects(schemaName);
    let maxId = invoiceList.max('id');
    let maxBillNumber = invoiceList.max('billNum');
    if (!maxId) {
      maxId = 0;
    }

    if (!maxBillNumber) {
      maxBillNumber = 0;
    }
    data.id = maxId + 1;
    data.billNum = maxBillNumber + 1;
    dataBase.insertNew(schemaName, data, Realm.UpdateMode.Never).then((response) => {
       event.sender.send('Database-Invoice-Insert', {response: response});
    });
  }).catch((error) => console.log(error));
}

In database.js

function insertNew(schemaName, data, mode = Realm.UpdateMode.Never) {
  return new Promise((resolve, reject) => {
    Realm.open(databaseConfig).then((realm) => {
      realm.write(() => {
        const response = realm.create(schemaName, data, mode);
        resolve(response);
      });
    }).catch((error) => {
      reject(error);
    });
  });
}

@nirinchev
Copy link
Member

That's a very roundabout way of inserting objects and is very inefficient, precisely because you open a new Realm instance for every insert. Since you have the Realm instance open in invoice.js, you can simply use that to insert your object. Also, as @kneth suggested, try to make sure your Promise.resolve's are outside the write blocks. So a simplified version of your code you can try would be:

function insertInvoice(event, arg) {
  const schemaName = arg.collection;
  const data = arg.data;
  return Realm.open(databaseConfig).then(realm => {
    const invoiceList = realm.objects(schemaName);
    let maxId = invoiceList.max('id');
    let maxBillNumber = invoiceList.max('billNum');
    if (!maxId) {
      maxId = 0;
    }

    if (!maxBillNumber) {
      maxBillNumber = 0;
    }
    data.id = maxId + 1;
    data.billNum = maxBillNumber + 1;
    let response;
    realm.write(() => {
      response = realm.create(schemaName, data, mode);
    });
    event.sender.send('Database-Invoice-Insert', { response });
  }).catch((error) => console.log(error));
}

But even that can be inefficient because you're opening a Realm for every invoice. An even better approach would be to store the opened Realm in a class-level variable and use it for all invoice inserts.

@jindalrohit
Copy link
Author

jindalrohit commented Jul 16, 2019

@nirinchev As you suggested I kept a single instance of Realm DB and used the same for each insert. It worked fine.

I wanted to view DB so I opened the db file in Realm Studio and same code stopped working immediately.

I closed the Realm Studio and again the code started working. Did this issue happen due to Realm Studio made a connection with DB and my application was also connecting with DB or something else? Kindly let me know.

@nirinchev
Copy link
Member

Are you using the local database (i.e. no sync)? If so, it's very surprising as Realm should support multi process access just fine. If you're using sync, then it's not supported to open the Realm files from your app directly - instead you should connect to your server with Studio and have it download a local copy of the synced Realm.

@jindalrohit
Copy link
Author

@nirinchev : I am using local database which has only 30 records as of now. I am developing a fully offline desktop application

@ccwdev
Copy link

ccwdev commented Jul 30, 2019

I have the same issue,
except it occurs on Windows and doesn't occur when developing on a mac.
Figuring that it could be an os-specific issue.

@kneth
Copy link
Contributor

kneth commented Aug 7, 2019

@ccwdev Can you post a code snippet which can reproduce the issue?

@RealmBot RealmBot changed the title Electron hangs while using realm.write() Electron hangs while using realm.write() Nov 12, 2019
@xmedeko
Copy link

xmedeko commented Mar 19, 2020

Still experiencing the problem with Realm 5.0.0 and Electron 8. It happens occasionally, when addListener() is followed by write() immediately. When I put some code between, e.g. console.debug('something'), the problems seems to vanish.
Test code:

const Realm = require('realm');

const CarSchema = {
    name: 'Car',
    properties: {
        make: 'string',
        model: 'string'
    }
};
const PersonSchema = {
    name: 'Person',
    properties: {
        name: 'string',
        birthday: 'date'
    }
};

exports.test = function() {
    return Realm.open({ schema: [CarSchema, PersonSchema], deleteRealmIfMigrationNeeded: true })
        .then(realm => {
            const n = 1000;
            for (let i = 0; i < 1000; i++) {
                console.log(`${i} iteration`);
                doTest(realm);
            }
            console.log(`${n} iterations successfully finished.`);
            realm.close();
        })
        .catch(error => {
            console.error(error);
        });
}

function doTest(realm) {
    const persons = realm.objects('Person');
    persons.addListener(personsListener);
    // console.debug('something'); // workaround
    realm.write(() => {
        const myCar = realm.create('Car', { make: 'Honda', model: 'Civic' });
    });
    persons.removeAllListeners();
    realm.write(() => {
        realm.deleteAll();
    });

    function personsListener() {}
}

Or download whole project from #2434 Run npm run start, open the developer console and click the Test bug button. The Electron freezes approx after 100 iterations on Windows 10. You can try it several times.

@richirich999
Copy link

I am using realm with Electron and adding the record in the db but application hangs after inserting the record. No error is displayed.

Electron : v4.1.4
Realm : v3.0.0-beta.1
Node.js : v10.15.1

Below is the code :

const PersonSchema = {
name: 'Person',
properties: {
firstName: 'string',
lastName: 'string',
fullName: 'string'
}
};

const config = {
path: 'C:\Users\user01\AppData\Roaming\invoice\database.realm',
schema: [PersonSchema]
};

Realm.open(config).then(function (realm) {
try {
realm.write(() => {
const john = realm.create('Person', {
firstName: 'first',
lastName: 'last',
fullName: 'first last'
}, Realm.UpdateMode.Never);
});
} catch (e) {
console.log("Error on creation : ", e);
}

}, function (error) {
console.log(error);
});

where did you write this? In main or renderer?

@richirich999
Copy link

@jindalrohit Can you please share your a part of your repo, so that I will be able to see the setup.

@kneth
Copy link
Contributor

kneth commented Sep 10, 2020

Please upgrade to a recent version. If you experience the issue in the future, please create a new issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants