Need some help for best practices with Structs


#1

I’ve been doing programming for the last 8 years with more than 14 languages including C++ and Go.
Based on my background for me it have been very easy to start programming with Rust.
So now I’m rewriting big Go project to Rust, for giving more integrations and performance than Go can give.
I’m not facing huge problems, but wanted to know some best practices using structs and dealing with “borrowed” variable errors.
For example

pub struct Server {
    // main socket for our server
    sock: TcpListener,

    // token of our server. we keep track of it here instead of doing `const SERVER = Token(0)`.
    token: Token,

    // a list of connections _accepted_ by our server
    conns: Slab<Connection>,

    // Channel for sending recieved event data
    sender: Sender<NetMsgInfo>,
}

This struct is one of the main structs that I have in my application and I’m using it’s props over all application. But main problem for me is that I can’t send struct property as an argument to another function.

fn handler_msg(token: Token, msg: Vec<u8>) {
    
}
............
............
// Getting borrowed variable error for s.token
handler_msg(s.token, ......)  

I’ve solved this “problem” by just sending cloned Token variable, but I’m thinking that this is not a best practice.

Is there some good code examples for understanding how to use Structs in rust in a right way ?

Thanks


#2

If I understand your question correctly, your handler_msg function uses moved token value. You can change handler_msg function signature to take token by reference:

fn handler_msg(token: &Token, msg: Vec<u8>) {
  ...
}

Please see simplified example: https://is.gd/2TwdRa


#3

@maksimsco thanks for replay.
I’ve played around your code https://is.gd/zgmNAW and found that my problem is in using immutable variables with pointers.
Thanks I figured it out, now I got better idea about what means “moving variable” !


#4

There is a great chapter on ownership in rust docs if you haven’t seen it yet: https://doc.rust-lang.org/book/ownership.html


#5

Just a guess. You may wish to use #[derive(Copy)] to implement the Copy trait for your token. Then you don’t have to copy it all the time.

https://doc.rust-lang.org/core/marker/trait.Copy.html


#6

@tigranbs
I would like to know if you’ve made benchmarks before porting the application from go to Rust because I’m suspicious that this will fix the performance problems. A lot of servers are limited by IO throughput/latency rather than CPU speed and we don’t have green threads, like go’s subroutines, at the moment in Rust.

PS: I don’t want to discourage your ambition porting your application to Rust, I’m just curious about the performance problems with go.


#7

@klingt.net I’ve been looking around making this transition over 3 moths already.
Main point for our project is to be more integratabtle as a library/SDK .
I’ve done event driven architecture based on Math Tree principles, so you are right, in most cases main problem is not a CPU performance, but I’ve started thinking about Rust because of the https://github.com/carllerche/mio project and his low level integrations.
As a benchmark I would say that we are getting only 5-10% of performance using MIO event system, but I think it’s not something that based on language specification.
I’ve decided to rewrite our engine with Rust and look what will happen :slight_smile: anyway it is a good experience learning Rust programming logic.


#8

To quote the mioco GitHub page:

Mioco uses asynchronous event loop, to cooperatively switch between coroutines (aka. green threads), depending on data availability.
You can think of mioco as Node.js for Rust or Rust green threads on top of mio.

Just because it’s not in the language itself or in the std library does not mean we don’t have it.


#9

Didn’t knew that, thanks!