ruby/rails grpc server restart without disconnecting clients - ruby-on-rails

I am using the following code snippet to start a grpc server which works fine. But whenever I need to deploy new code to the server, what is the right way for me to restart the server? Should I just kill the server process, and let client to handle the error message? Or is there a way for enabling master/worker mode like unicorn does?
s = GRPC::RpcServer.new
s.run_till_terminated

There is no such support for rolling out new deployments that's built in to the ruby-gRPC.
However, it should be possible for applications with multiple server instances to do rolling restarts. E.g., note that if gRPC connects to a server and starts to make RPC's to it and that server gets shut down, then gRPC will internally notice that the connection went bad and it will try to make its next RPC on a newly connection (the default gRPC behavior will be to perform its next RPC on the next resolved address that can be successfully connected to, and this might mean reconnecting to the same address for which the connection just broke). Note too that gRPC servers use SO_REUSEPORT by default, so one could potentially run multiple servers on the same port.

Related

How do I connect an Ado.Net client to my NuoDB on Linux Docker

I created the 3 necessary containers for NuoDB using the NuoDB instructions.
My Docker environment runs on a virtual Ubuntu Linux environment (VMware).
Afterwards I tried to access the database using a console application (C# .Net Framework 4.8) and the Ado.Net technology. For this I used the Nuget "NuoDb.Data.Client" from Nuget.org.
Unfortunately the connection does not work.
If I choose port 8888, my thread disappears to infinity when I open the connection.
For this reason I tried to open the port 48004 to get to the admin container.
On this way I get an error message.
"System.IO.IOException: A connection attempt failed because the remote peer did not respond properly after a certain period of time, or the established connection was faulty because the connected host did not respond 172.18.0.4:48006, 172.18.0.4"
Interestingly, if I specify a wrong database name, it throws an error:
No suitable transaction engine found for database.
This tells me that it connects to the admin container.
Does anyone have any idea what I am doing wrong?
The connection works when I establish a connection with the tool "dbvisualizer".
This tool accesses the transaction engine directly. For this reason I have opened the port 48006 in the corresponding container.
But even with these settings it does not work with my console application.
Thanks in advance.
Port 8888 is the REST port that you would use from the administration tool such as nuocmd: it allows you to start/stop engines and perform other administrative commands. You would not use this port for SQL clients (as you discovered). The correct port to use for SQL clients is 48004.
Port 48004 allows a SQL client to connect to a "load balancer" facility that will redirect it to one of the running TEs. It's not the case that the SQL traffic is routed through this load balancer: instead, the load balancer replies to the client with the address/port of one of the TEs then the client will disconnect from the load balancer and re-connect directly to the TE at that address/port. For this reason, all the ports that TEs are listening on must also be open to the client, not just 48004.
You did suggest you opened these ports but it's not clear from your post whether you followed all the instructions on the doc page you listed. In particular, were you able to connect to the database using the nuosql command line tool as described here? I strongly recommend that you ensure that simple access like this works correctly, before you attempt to try more sophisticated client access such as using Ado.Net.

Run proxy server on iOS

For an enterprise application I want to run a proxy server continuously locally on iOS. Steps I have taken so far:
Use NEPacketTunnelProvider to create a tunnel
Tunnel the traffic to 127.0.0.1:8080
Start Proxy Server from the network extension (this works!)
Step 3 works, however, it seems like after starting up it stops working. I could imagine this having to do something with not being able to run such a process continuously. Does anyone have an idea or a pointer?

Docker Swarm load balance testing using Chrome

I've tried doing simple single node swarm just like in Docker tutorial part 3 and I've found out that if I use curl then I'm jumping between two replicas, but if I use Chrome then once I open the page then any following requests will be handled by the same replica. I'm sure I'm actually hitting it only once, because counter increases only by 1.
What is happening? Is it some kind of feature in Docker Swarm load balancing? If so, how would it work? No specific request headers are send to the server, so how would the load balancer recognize me? It can't be IP, because if I use incognito mode I'll be handled by different replica and I'll be stick to it as long as I'm in incognito.
It's not a Swarm thing, it's a chrome thing. Curl acts like you'd expect, each command is a new TCP request that shows as a new connection going through the Swarm VIP load balancer.
Chrome (and other browsers) have lots of methods to keep TCP connections open for future requests (HTTP keep-alives, etc). This is why it will stay connected to the same container because the connection is persistent through the LB to the replica. The LB will only shift to the "next in the round-robin pool" for a new connection.

Docker services stops communicating after some time

I have together 6 containers running in docker swarm. Kafka+Zookeeper, MongoDB, A, B, C and Interface. Interface is the main access point from public - only this container publish the port - 5683. The interface container connects to A, B and C during startup. I am using docker-compose file + docker stack deploy, each service has a name which is used as host for interface. Everything starts successfully and works fine. After some time (20 mins,1h,..) I am not able to make request to interface. Interface receives my requests but application lost connection with service A,B,C or all of them. If I restart interface, it's able to reconnect to services A,B,C.
I firstly thought it's problem of application so I expose 2 new ports on each service (interface, A,B,C) and connect with profiler and debugger to them. Application is running properly, no leaks, no blocked threads, normally working and waiting for connections. Debugger shows me that when I make a request to interface and interface tries to request service A, Connection reset by peer exception was thrown.
During this debugging I found out interesting stuff. I attached debugger to interface when the services started and also debugger was disconnected after some time. + I was not able to reconnect it, until I made request to the container -> application. PRoblem - handshake failed.
Another interesting stuff that I found out was that I was not able to request neither interface. So I used wireshark to see what's going on and: SYN - ACK was fine. Then application post some data and interface respond with FIN,ACK. I assume that this also happen when interface tries to request service A and it FIN the connection. Codebase of Interface, A,B and C is the same regarding netty server.
Finally, I don't think it's a application issue. Why? I tried to deploy containers not as services. I run each container separately, published the ports of each and endpoint of services were set to localhost. (not overlay network). And it is working. Containers run without problem. + I didn't say at the beginning, that the the java applications (interface, A,B,C) runs without problem when they are running as standalone application - not in docker.
Could you please help me what could be the issue? Why the docker in case of overlay network is closing sockets?
I am using newest docker. I used also older.
Finally, I was able to solve the problem.
What was happening, one more time. Interface opens permanent TCP connection to A,B,C. When you try to run these services A,B,C as a standalone java applications, everything is working. When we dockerize them and run in swarm, it was working only few minutes. Strange was that the connection between Interface and another service was interrupted in the moment when you made a request from client to interface.
After many many unsuccessful tests and debugging each container I tried to run each docker container separately, with mapped ports and as endpoint I specified localhost. (each container exposed ports and interface was connecting to localhost) Funny thing happen, it was working. When you run containers like this, different network driver for container is used. Bridge one. If you run it in swarm, overlay network driver is used.
So it had to be something with the docker network, not with application itself. Next step was tcpdump from each container after couple of minutes, when it should stop working. It was very interesting.
Client -> Interface (OK, request accepted)
Interface ->(forward request because it belongs to A) A
Interface -> A [POST]
A -> Interface [RESET]
A was reseting opened TCP communication after couple of minutes without communication. Why?
Docker uses IP Virtual Server and IPVS maintains its own connection table. The default timeout for CLOSE_WAIT connections in IPVS table is 60 seconds. Hence when the server sends something after 60 seconds, the IPVS connection is no longer available and the packet looks invalid for a new TCP session and gets RST. On the client side, the connection remains forever in FIN_WAIT2 state because the app still has the socket open; kernel's fin_wait timer kicks in only for orphaned TCP sockets.
This is what I read about it and how understand it. I am not sure if my explanation of problem is correct, but based on these assumptions I implemented ping-pong between Interface and A,B,C services in case there is no communication for <60seconds. And, it’s working.
Got the same issue.
Specified
endpoint_mode: dnsrr
to properties of the service which plays "server" role and it works just fine.
https://forums.docker.com/t/tcp-timeout-that-occurs-only-in-docker-swarm-not-simple-docker-run/58179

How can i connect to remote server for CPU process time monitoring?

I want to connect to remote server to monitor the cpu process time when i run the stress test.
But it always failed, what can i do to successfully connect to remote server ?
If you are using linux, you can ssh into the remote server by knowing its hostname and ip as explained here.
You also require to know the root password of the remote server.
To check the CPU process time, memory ,etc during the stress test, you can use SeaLion.
It allows you to monitor the output of commands like top, free -m,etc on a graphical inteface, thus everytime you perform your test, you wouldn't require to connect to the remote server.
There is also New Relic which is extremely feature rich and provides many functionalities like graphing, etc.

Resources