logo
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
//! ## CSE 223B Labs
//!
//! Welcome to CSE 223B. Below you'll find some information on setting up an
//! environment to complete the labs for the course. Instructions for each lab
//! can be found at
//!
//! - [Lab 1](lab1)
//! - [Lab 2](lab2)
//! - [Lab 3](lab3)
//!
//! ## Programming Language
//!
//! You will write the labs in the [Rust](https://www.rust-lang.org/)
//! programming language. It is a community-developed language originally
//! started at Mozilla. Rust is a low-level language which eschews any kind of
//! managed runtime like you might find in Java, Python, or Go. Rust's main
//! selling point is it's **compile-time** [borrow
//! checker](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html)
//! that prevents invalid memory accesses at runtime.
//!
//! Here is some key documentation on the Rust programming language:
//!
//! - ["The Book"](https://doc.rust-lang.org/book/title-page.html)
//! - [Rust By Example](https://doc.rust-lang.org/rust-by-example/)
//! - [Learn Rust Page](https://www.rust-lang.org/learn)
//! - [The Rust Playground](https://play.rust-lang.org/)
//!
//! You should be able to find a lot of documents about the Rust language on the
//! web, especially from the official site. **[We highly recommend reading "The
//! Book"](https://doc.rust-lang.org/book/title-page.html)** and following parts
//! of the [Rustlings](https://github.com/rust-lang/rustlings/) course.
//!
//! **Rust takes time to understand and has a steep learning curve**. In the
//! early stages of using the language, getting your program just to compile
//! might take you 30 minutes or more. **Do not underestimate the amount of time
//! you will need** to spend working on these assignments. Start early, **[read
//! the book](https://doc.rust-lang.org/book/title-page.html)**, and search on
//! the web if you have problems compiling your program. **Read the compiler
//! error messages too**. The Rust compiler has some of the most helpful error
//! messages of all modern languages. If that doesn't help, try **[reading the
//! book again](https://doc.rust-lang.org/book/title-page.html)**. Finally, if
//! you still can't figure out your issue ask for help on piazza or come to
//! office hours if you truly feel stuck.
//!
//! **[READ THE BOOK](https://doc.rust-lang.org/book/title-page.html)**
//!
//! ---
//!
//! ### Install Rust
//!
//! To get started with the Rust language, we recommend using the official
//! [`rustup`](http://rustup.sh/) tool. This will install the latest stable Rust
//! toolchain along with a number of programs useful for building applications
//! with the language.
//!
//! #### Cargo
//!
//! The most important tool you'll need from the toolchain is `cargo`. `cargo`
//! is a user-friendly wrapper around the rust compiler (rustc) and handles
//! downloading, compiling, testing, formatting, checking, linting, documenting
//! Rust code, and more.
//!
//! Cargo looks for a manifest file, `Cargo.toml` in your current directory to
//! figure out exactly which files it needs to build, test, or run. The file can
//! define dependencies, build options, metadata and many other options. You
//! shouldn't need to modify any `Cargo.toml` files for these assignments.
//!
//! Here are some of the most useful cargo commands
//!
//! - `cargo build` will compile your code with no optimization
//!     - `cargo build --release` compiles with optimizations (e.g. similar to
//!       `gcc -O2`)
//!     - all compilation output can be found in the `./target` directory
//! - `cargo test` runs all of the tests defined in the projects
//!     - `cargo test --tests` runs integration tests
//!     - `cargo test -p <package>` runs all of the tests in `<package>`
//! - `cargo fmt` will format your code according to standard Rust formatting
//!   guidelines
//! - `cargo check` looks for compilation errors in packages and dependencies.
//!   It basically performs compilation without the final step of code
//!   generation. It is faster than `cargo build` for checking if your code
//!   compiles.
//! - `cargo run` can run binaries defined in `Cargo.toml`
//!     - `cargo run --bin <bin-name>` will run the `<bin-name>` binary
//!     - pass arguments to the binary with `cargo run --bin <bin-name> --
//!       <arg1> <arg2> ...`
//!
//! #### Clippy
//!
//! Rust also has a non-default code linting tool called Clippy. It can help
//! point out simple optimizations and make your code more idiomatic. Clippy is
//! entirely optional to use, but is immensely helpful in identifying use of
//! anti-patterns in your code.
//!
//! - To install clippy: `rustup component add clippy`, then try running with
//!   `cargo clippy`
//!
//! #### Basic Rust Concepts
//!
//! It is difficult to cover all of Rust's great (and not-so great) features. We
//! recommend thoroughly reading through ["The
//! Book"](https://doc.rust-lang.org/book/title-page.html) or [Rust By
//! Example](https://doc.rust-lang.org/rust-by-example/) to learn the ins and
//! outs of the language. Below we try to highlight some of the most important
//! concepts you should understand.
//!
//! - Rust code is organized into *crates* and *modules*
//!   - a set of modules make up a crate.
//! - Compile, run, and format code with `cargo` (`build`, `run`, `fmt`)
//! - Once cargo is installed, view documentation for the crate and dependencies
//!   with `cargo doc --open`
//! - In Rust, variables must be explicitly defined as mutable using the `mut`
//!   keyword.
//! - References to variables in Rust can be *owned* or *borrowed*.
//! - `Vec<T>` is the standard type used to represent a series of items, similar
//!   to C++. Array types (`[T; usize]`) are rarely used. Usually you should opt
//!   for a slice (`&[T]`)
//! - `std::collection::HashMap` or `std::collections::BTreeMap` can be used to
//!   store a set of key-value pairs.
//! - The `Result<T, E>` is the standard return type used for functions which
//!   might return errors. When calling a function which returns a result, use
//!   the `?` operator after the `()` to unwrap the result to type `T`
//! - some built-in macros that you might find useful are `unimplemented!()`,
//!   `todo!()`, `println!()`, `print!()`, and `format!()`.
//! - you can write a loop using the `loop` keyword and run a function over an
//!   iterator with `for x in a.iter()`
//! - values are returned from functions by simply omitting the trailing
//!   semicolon `;` at the end of a statement.
//! - Store items on the heap using the `Box<T>` type.
//! - You can write interfaces in Rust using the `trait` keyword, and then
//! implement a trait for a specific struct with `impl <Trait> for <Struct> {
//! ... }`
//!
//! ## The Tribbler Story
//!
//! Some cowboy programmer wrote a simple online microblogging service called
//! Tribbler and, leveraging the power of the Web, it becomes quite popular.
//! However, the program runs in a single process on a single machine; it does
//! not scale, cannot support many concurrent connections, and is vulnerable to
//! machine crashes. Knowing that you are taking the distributed computing
//! system course at UCSD, he asks you for help. You answered his call and are
//! starting work on this project.
//!
//! Your goal is to refactor Tribbler into a distributed system, making it more
//! robust and scalable.
//!
//! ## Getting Started
//!
//! We will be using Github Classroom to distribute assignments and manage
//! submissions. We will send out invitation links for each individual lab
//! through Piazza/Canvas. Once you access these links, a GitHub repository
//! containing Tribbler starter code will be created for you. It comes with
//! necessary instructions on how to setup environment before you start, and
//! submit your work when you are done.
//!
//! Once you download your first lab (and before you start working on it), you
//! can run the basic version of Tribbler. The Tribbler project is written in
//! Rust. To get started, run these commands from the command line:
//!
//! You can do some basic testing to see if the framework is in good shape:
//!
//! ```console
//! $ cargo test -p tribbler
//! ```
//!
//! The basic Tribbler service should now be installed on the system from your
//! home directory. Let's give it a try:
//!
//! ```console
//! $ cargo run --bin trib-front
//! ```
//!
//! The program should show the URL it is running under.
//!
//! Open your browser and type in the address: `http://<host-name>:<port>`. For
//! example, if you are using your local machine, and Tribbler is running on
//! port 8080, then open `http://localhost:8080`. If you are using AWS EC2
//! machine, you can use its public DNS name as host name (make sure to allow
//! traffic on this port to your instance). You should see a list of Tribbler
//! users. You can view their tribs and login as them (with no authentication).
//!
//! This is how Tribbler looks to users.  It is a single web page that performs
//! AJAX calls (a type of web-based RPC) to the back-end web server. The
//! webserver then in turn calls the Tribbler logic functions and returns the
//! results back to the Web page in the browser.
//!
//! ## Source Code Organization
//!
//! The source code in the `trib` package repository is organized as follows:
//!
//! - `lab` has the skeleton code for completing the class assignments
//! - [tribbler] defines the common Tribbler interfaces and data structures.
//! - [tribbler::ref_impl] is a reference monolithic implementation of the
//!   [Server](tribbler::trib::Server) interface. All the server logic runs in
//!   one single process. It is not scalable and is vulnerable to machine
//!   crashes.
//! - [tribbler::storage] contains an in-memory thread-safe implementation of
//!   the [tribbler::storage::Storage] interface. We will use this as the basic
//!   building block for our back-end storage system.
//! - [tribbler::addr] provides helper functions that check if an address
//!   belongs to the machine that the program is running.
//! - [tribbler::addr::rand] provides helper functions that generate a network
//!   address with a random port number.
//! - [tribbler::colon] provides helper functions that escape and unescape
//!   colons in a string.
//! - `lab/tests` provides several basic test cases for the interfaces.
//! - `cmd/src/trib_front.rs` is the web-server launcher that you run.
//! - `cmd/src/kv_client.rs` is a command line key-value RPC client for quick
//!   testing.
//! - `cmd/src/kv_server.rs` runs a key-value service as an RPC server.
//! - `cmd/src/bins_client.rs` is a bin storage service client.
//! - `cmd/src/bins_back.rs` is a bin storage service back-end launcher.
//! - `cmd/src/bins_keep.rs` is a bin storage service keeper launcher.
//! - `cmd/src/bins_mkcfg.rs` generates a bin storage configuration file.
//! - `www/` contains the static files (html, css, js, etc.) for the web
//!   front-end.
//!
//! **Don't be scared by the number of modules**. Most of the modules are very
//! small, and you don't have to interact with all of them at once. All Rust
//! language files under the `tribbler` directory are less than 2500 lines in
//! total, so these packages aren't huge and intimidating.
//!
//! Throughout the entire lab, you do not need to (and should not) modify
//! anything in the [tribbler] crate. If you feel that you have to change some
//! code to complete your lab, please first discuss it with the TA. You are
//! always welcome to read the code in the tribbler crate or read its
//! [documentation][tribbler]. If you find a bug and report it, you might get
//! some bonus credit.
//!
//! ## Your Job
//!
//! Your job is to complete the implementation of the `lab` package.
//!
//! It would be good practice for you to periodically commit your code into your
//! git repo.
//!
//! ## Lab Roadmap
//!
//! - [Lab 1](crate::lab1). Wrap the key-value storage service with RPC so that
//!   a remote client can store data remotely.
//! - [Lab 2](crate::lab2). Reimplement the Tribbler service, splitting the
//!   current Tribbler logic into stateless scalable front-ends and scalable
//!   key-value store back-ends. The front-ends will call the back-ends via the
//!   RPC mechanism implemented in Lab 1. When this lab is done, you will have
//!   made both the front-end and the back-end scalable.
//! - [Lab 3](crate::lab3). We make the back-ends fault-tolerent with
//!   replication and by using techniques like distributed hash tables. At the
//!   end of this lab, back-end servers can join, leave, or be killed, without
//!   affecting the service.
//!
//! By the end of the labs, you will have an implementation of Tribbler that is
//! scalable and fault-tolerant.
//!
//! ## Misc
//!
//! You can write your code on your own machine if you want to. See `rustup`
//! language's [install](http://rustup.sh/) page for more information on how to
//! install in different environments
//!
//! Visual Studio Code (VSCode) has SSH extensions to help with remote
//! development and the
//! [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=matklad.rust-analyzer),
//! Rusts's community supported language server, which can make editing rust
//! code easier. If you want to use a remote developement environment on AWS
//! with rust-analyzer, you might need to upgrade to a larger instance type
//! (e.g. a t3.medium) to accomodate the larger memory footprint of running
//! rust-analyzer.
//!
//! Unless noted by the TA or instructor, **no dependencies should be added to
//! `Cargo.toml`**. If you feel you need to add an additional dependency to
//! complete one of the lab assignments, consult with the instructor or TA.
//!
//! ## Ready?
//!
//! If you feel comfortable with the lab setup, continue on to [Lab 1](lab1).
//!
#![doc(
    html_logo_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Creative-Tail-Animal-penguin.svg/480px-Creative-Tail-Animal-penguin.svg.png"
)]
#![doc(
    html_favicon_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Creative-Tail-Animal-penguin.svg/128px-Creative-Tail-Animal-penguin.svg.png?20160314145218"
)]
mod keeper;
pub mod lab1;
pub mod lab2;
pub mod lab3;