Unable to replicate database in pouchDB - timeout

I'm trying a react native application using couchDB 2.1.1. PouchDB entry in package json looks like this:
"pouchdb": "^6.3.4",
"pouchdb-react-native": "^6.3.4",
Replication is as shown below:
const localDB = new PouchDB('employee');
const remoteDB = new PouchDB('http://username:password#localhost:5984/employee');
localDB.replicate.from(
remoteDB,
(err, response) => {
if (err) {
return console.log(err);
}
},
);
I get following error:
{"code":"ETIMEDOUT","status":0,"result":{"ok":false,"start_time":"...","docs_read":0,"docs_written":0,"doc_write_failures":0,"errors":[],"status":"aborting","end_time":"...","last_seq":0}}
Almost all the times this works fine when I run the app in debug mode. Tried ajax timeout as shown here PouchDB ETIMEDOUT error. This didn't work. Is there something that I'm supposed to look in my code? Please help.

Had the same issue, the following fixed it for me:
Use your PC ip address instead of localhost
Configure your firewall
to allow connections on port 5984 OR just disable it (Not
recommended)

Related

Protocol error when calling puppeteer.connect()

I am using the basic approach as set out in this post to connect from a client docker container to any one of a number of chrome docker containers (in a docker swarm/service, potentially across several servers behind nginx, deployed using CapRover).
In each chrome container I maintain a pool (just a simple array) of browser objects, and direct incoming requests to an appropriate browser as follows (very similar to the linked post):
import http from 'node:http'; // https://nodejs.org/api/http.html
import httpProxy from 'http-proxy'; // https://www.npmjs.com/package/http-proxy
const proxy = new httpProxy.createProxyServer({ ws: true });
// an array (pool) of pre-launched and managed browser objects...
const browsers = [ ... ];
http
.createServer()
.on('upgrade', (req, socket, head) => {
const browser = browsers[Math.floor(Math.random() * browsers.length)]; // in reality I don't just pick a browser at random
const target = browser.wsEndpoint();
proxy.ws(req, socket, head, { target });
})
.listen(3222);
The above is listening at ws://srv-captain--chrome:3222 (communication is "internal" over the docker network between containers).
Then, in my client container, I connect to the common endpoint ws://srv-captain--chrome:3222 as follows:
import puppeteer from 'puppeteer'; // https://www.npmjs.com/package/puppeteer (using version 17.1.3 at time of posting this)
try {
const browser = await puppeteer.connect({ browserWSEndpoint: 'ws://srv-captain--chrome:3222' });
} catch (err) {
console.error('error connecting to browser', err);
}
This works really well, except that I am getting occasional/inconsistent errors like these when calling puppeteer.connect() in the client container above:
Protocol error (Emulation.setDeviceMetricsOverride): Session closed. Most likely the page has been closed.
Protocol error (Performance.enable): Target closed.
Almost always, if I simply try to connect again, the connection is made without further error, and at the first attempt.
I have no idea why the error is complaining that the page has been closed or Target closed since, at this point in the process, I'm not attempting to interact with any page, and I know from listening for browser.on('disconnected'...), and also monitoring the chromium processes themselves, that each browser in the array is still working fine... none has crashed.
Any idea what's going on here?
UPDATE after further testing
Of course, in the client container we don't connect to a browser just for the sake of it, like in the above snippet, but to open a page and do some stuff with the page. In practice, in the client container it's more like the following test snippet:
const doIteration = function (i) {
return new Promise(async (resolve, reject) => {
// mimic incoming requests coming in at random times over a short period by introducing a random initial delay...
await new Promise(resolve => setTimeout(resolve, Math.random() * 5000));
// now actually connect...
let browser;
try {
browser = await puppeteer.connect({ browserWSEndpoint: `ws://srv-captain--chrome:3222?queryParam=loop_${i}` });
} catch (err) {
reject(err);
return;
}
// now that we have a browser, open a new page...
const page = await browser.newPage();
// do something useful with the page (not shown here) and then close it..
await page.close();
// now disconnect (but don't close) the browser...
browser.disconnect();
resolve();
});
};
const promises = [];
for (let i = 0; i < 15; i++) {
promises.push( doIteration(i) );
}
try {
await Promise.all(promises);
} catch (err) {
console.error(`error doing stuff`, err);
}
Each iteration above is being performed multiple times concurrently... I am using Promise.all() on an array of iteration promises to mimic multiple concurrent incoming requests in my production code. The above is enough to reproduce the problem... the error doesn't happen on calling puppeteer.connect() with every iteration, just some.
So there seems to be some sort of interplay between opening/closing a page in one iteration, and calling puppeteer.connect() in another, despite closing the page and disconnecting the browser properly in each iteration? This probably also explains the Most likely the page has been closed error message when calling puppeteer.connect() if there is some hangover relating to a page closed in another iteration... though for some reason this error occurs when calling puppeteer.connect()?
With the use of a pool of browser objects in the browsers array, and a docker swarm having multiple containers on multiple servers, each upgrade message could be received at a different container (which could even be on a different server) and could be routed to a different browser in the browsers array. But I now think that this is a red herring, because in the further testing I narrowed the problem down by routing all requests to browsers[0] and also scaling the service down to just one container... so that the upgrade messages are always handled by the same container on the same server and routed to the same browser... and the problem still occurs.
Full stacktrace for the above-mentioned error:
Error: Protocol error (Emulation.setDeviceMetricsOverride): Session closed. Most likely the page has been closed.
at CDPSession.send (file:///root/workspace/myclientapp/node_modules/puppeteer/lib/esm/puppeteer/common/Connection.js:281:35)
at EmulationManager.emulateViewport (file:///root/workspace/myclientapp/node_modules/puppeteer/lib/esm/puppeteer/common/EmulationManager.js:33:73)
at Page.setViewport (file:///root/workspace/myclientapp/node_modules/puppeteer/lib/esm/puppeteer/common/Page.js:1776:93)
at Function._create (file:///root/workspace/myclientapp/node_modules/puppeteer/lib/esm/puppeteer/common/Page.js:242:24)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Target.page (file:///root/workspace/myclientapp/node_modules/puppeteer/lib/esm/puppeteer/common/Target.js:123:23)
at async Promise.all (index 0)
at async BrowserContext.pages (file:///root/workspace/myclientapp/node_modules/puppeteer/lib/esm/puppeteer/common/Browser.js:577:23)
at async Promise.all (index 0)
As I dug deeper and deeper into this problem, it become more and more apparent that I might not actually be doing anything fundamentally wrong, and that this might just be a bug in puppeteer itself. So I reported those as an issue over on puppeteer... and indeed, it is acknowledged as a bug for any version later than 15.5.0, and is being fixed. In the meantime, the workaround is to revert to puppeteer version 15.5.0 and to be careful when calling browser.pages() when concurrent connections are being used, because that might itself throw an error... but I understand that this too might be something that they can/will fix so that browser.pages() is more resilient to the presence of concurrent connections.

How do I get my physical device running React Native on Expo Go to communicate with my app's rails backend api?

I am currently trying to run my react-native/rails app on my phone for testing purposes. I can run my sign in and log in screens fine because they do not communicate with my server until the user info is entered. When running my server i use:
$ rails s --binding=0.0.0.0
I do not receive any errors other than knowing my server is not being communicated with. This all works fine on my Android Studio Emulator as well.
// one of my fetch GET requests
export function requestCurrentUser(username, auth_token) {
return function action(dispatch) {
const request = fetch(`'http://10.0.2.2:3000'/users/${username}`, {
method: 'GET',
headers: {
"Authorization": auth_token
}
});
return request.then(
response => response.json(),
err => console.log("user error"),
)
.then(
json => dispatch(receiveCurrentUser({id: json.id, email: json.email, username: json.username})),
err => console.log("user json error"),
);
}
}
I've tried changing my Phone IP settings to a 10.0.2.2 Gateway, and using my phone's IP in my fetch request. I feel like I am missing something conceptually. Thanks in advance.
In fetch request you need to use the IP from the machine that are running the rails server,
probably your notebook and use the same network to connect your app and your rails backend api. In order to test, you can try directly access your api in your phone browser accessing http://IP_FROM_RAILS_MACHINE:3000

ApolloServer: "Could not connect to websocket endpoint ws://localhost:4000/subscriptions. Please check if the endpoint url is correct."

I can't implement any subscriptions because it suddenly disconnects from it when I try to listen to some endpoint with GraphQL Playground:
{"error": "Could not connect to websocket endpoint wss://localhost:4000/graphql. Please check if the endpoint url is correct."}
I'm using ApolloServer alone, no express or anything else. It is containerized with Docker using node14 image, the port is properly fowarded, queries and mutations works properly.
This is the configuration snippet:
const server = new ApolloServer({
typeDefs: mergedTypeDefs,
resolvers: mergedResolvers,
playground: {
subscriptionEndpoint: 'ws://localhost:4000/graphql'
},
subscriptions: {
keepAlive: 9000,
onConnect: (connParams, webSocket, context) => {
console.log('CLIENT CONNECTED');
},
onDisconnect: (webSocket, context) => {
console.log('CLIENT DISCONNECTED')
}
},
context: {
models
}
});
I tried everything, from using 'wss' instead of 'ws' to change the path. I checked for typos and didn't find one. What bothers me is that the paths are the same so It should at least try to notify me by the onConnect or onDisconnect but it doesn't.
This is the message through Chrome's dev tools:
WebSocket connection to 'wss://localhost:4000/graphql' failed: WebSocket is closed before the connection is established.
I tested subscriptions with a 'tutorial' project outside the container and it works fine.
Sometimes, the only function of subscriptions that works is onDisconnect but after 2-5 seconds after receiving the error message on PlayGround, and Still it doesn't gives me any insight on the problem.
Any help or suggestion is appreciated.
wss will definitely not work locally without certificate, so use ws as a protocol.
If it works without Docker, then everything should be fine code-wise.
You should also make sure that you've mapped ports correctly, i.e. exposed port 4000 https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose

Can't connect to server with socket.io on both client and server

I just started building me server using socket.io for both my client and Node.js server side.
I'm writing an Objective-c project so i walk through the process of adjusting my project to use Swift alongside with Objective-c which was a pain but it seems to be ok now.
The thing is, when i try to do a simple connect to my server, which prints to log on each connection, nothing happens.
This is the code for the server (Taken from here):
var fs = require('fs')
, http = require('http')
, socketio = require('socket.io');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/html'});
}).listen(8080, function() {
console.log('Listening at: http://localhost:8080');
});
socketio.listen(server).on('connection', function (socket) {
console.log('Connected');
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
Super simple, really nothing to it.
And the Objective-c code for my client which is even more simple:
- (void) connect
{
SocketIOClient* client = [[SocketIOClient alloc]initWithSocketURL:#"http://127.0.0.1:8080/" options:nil];
[client connect];
}
But i can't see nothing on my console except the Listening at: http://localhost:8080 message.
I can't seem to find what i'm doing wrong here, and the fact that the swift debugging is horrible in this combined project, i can't really fully go through the socket.io debugging myself (but i'm pretty sure nothing's wrong with their code)
Any help would be much appreciated.
plz confirm, if you are using the simulator for iOS testing. For device, you need to assign public address to your NodeJS server, and then need to use it's ip in iOS Codebase.
I had used https://github.com/pkyeck/socket.IO-objc during my last project and it worked like a charm.
For simulator, your code should ideally work.

socket.io/1/?t= not found

I have a web app that is running on rails 4 at localhost:3000. I am also have angularjs on client side. I have placed scoket.io.js file in my rails app public folder. From my angularjs client code, I run this code
this.connect = function (endpoint) {
if(!socket) {
socket = io.connect(endpoint);
socket.on('connect', connectHandler);
socket.on('connect_failed', connectFailedHandler);
socket.on('message', messageHandler);
socket.on('disconnect', disconnectHandler);
socket.on('close', disconnectHandler);
socket.on('nexus_disconnect', this.disconnect);
} else {
socket.socket.connect(endpoint);
}
};
I am getting error as below on my browser console.
http://localhost:3000/socket.io/1/?t=1405687049255 404 (Not Found)
Is any server other than rails server needed for socket.io?
Yes, you have to set up Node.js server.
There are several implementations of Socket.IO server in other languages, but it seems that there is no one written in Ruby.

Resources