Go application porting


#1

Hi guys! I hope this is the appropriate place to ask for clarifications. :slight_smile:

the problem

We have a little piece of code in production that do a business critical operation. The application is really simple: is an HTTP server (supporting both CORS and JSONP) listening on a port that allows web pages to communicate with thermal printers in the local network, analyze the response code to ensure that the print job completed successfully and send to the webpage an OK or a KO. This application is written in Go and works like a charm. If not that on windows the socket read is slow as fuck and I cannot understand what is the issue. It’s just a minor annoyance, because it’s not blocking, just slower (+1s for print, easily noticeable). The problem is that is “forcing” our client to use linux, and I want to give them freedom of choice, and Go was chosen for his easy cross-compilation.

my question (sorry for the long introduction)

I finally got fed up with this issue and decided to use this as an excuse to finally learn Rust using a real project. The only problem that I have is that I’m not sure that Rust is the right choice for this kind of application because, as far I know hence me asking here, I cannot understand if it the existing HTTP libraries are blocking or not. My fear is that the trip Browser -> HTTPlib -> socket -> printer -> socket -> HTTPlib -> Browser will result too slow because the I/O on the socket that could make unresponsive the application when reading/writing. So unfortunately the real issue here is my ignorance, but I haven’t time to research the issue at hand on my own. I’m not asking for code, only guidance towards the right libraries, pieces of literature or advices that could help me wrap my mind around this issue.

Thanks :smile:


#2

Fix the go/windows issue first. If the problem is caused by some os settings its likely that you will have the same slowdown regardless of the language. Once you’ll have this working you’ll know more about network protocols and it will be easier to optimize it with whatever language you’ll choose.

As for blocking in rust - will find both synchronous (hyper) and asynchronous (rotor) libraries for rust.


#3

I don’t think Rust will really scale to the same level of networking as easily as Go, due to Rust not having stackless light-weight threading (N : M concurrency).

Yes you could write your own thread-pool, and use all asynchronous and plumb everything into a top-level event loop, but it will be much more complicated than writing some goroutines.


#4

That’s the point, I’ve tried every single piece of advice related to Go and networking that I could find around, from setting TCP_NODELAY to false/true, to reading from socket using ioutil etc. So what I’m trying to do is change the approach changing language (is a really small codebase, so it’s worth a try) to better understand the problem domain and see if the problem remains. I’m not throwing away the entire codebase of course, it’s serving its purpose very well and I’m not done trying to fix this problem. :slight_smile:

Thanks! :+1:


#5

That was my fear. Luckily the throughput is very low so I’m not particularly worried about general performance, only to keep the application responsive when sending a request, so if the solution is not optimal is still good enough (for it’s purpose and for now). Thanks!


#6

FYI, if you’re not seeking super high throughput, an alternative to async code is just having a thread per connection - for most use cases this should be plenty fast enough, even though Rust uses OS threads rather than m:n threading.


#7

I agree, speed should not be an issue with Rust, and the thread per connection model works well as long as you have plenty of RAM for all the thread stacks. Where you run into problems is if you make blocking calls to any high latency services like databases or other network services.


#8

I have to, I can only respond when the printer has finished printing, so every call take roughly 1sec. Although this is unavoidable, so using native threads could be the good enough solution I’m searching. I don’t know if I will or won’t implement this in rust as I’m still thinking about if it’s worth the time, but thank you all very much for taking the time to help me, it has been very appreciated! :smile: