text:
RFC: Socket timeouts

Add sockopt-style timeouts to std::net types.
Rendered

cc @sfackler @carllerche @alexcrichton

Seems good and simple.

Wait for Duration to be stable. Socket timeouts can be implemented in user land, so there is no huge rush

There should be a way to get the current timeout as well.

I'm not too concerned with drawback. Abstractions that accept a reader should not care about timeouts. Timeouts are an ops level concern and should probably be specified at the "edge". If an abstraction needs to set a timeout, it should probably take ownership of the socket.

cc me, @seanmonstar

:+1: Though I agree with @carllerche that we'll want getters too.
It might be worth putting the methods on a Timeout trait. I ended up defining my own when rust-postgres was on oldio since it needs to abstract over TCP and Unix sockets: https://github.com/sfackler/rust-postgres/blob/df4d5d8417ddd1f421388aefb1d09f266e5168c3/src/io.rs#L15-L30

It does feel moderately janky to use Duration::zero() to unset the timeout. Should the argument be an Option<Duration> instead? None and Some(Duration::zero()) would end up doing the same things, but that's not the end of the world.

What about connection timeouts? They are usually as important as read timeouts, if not more.

@netvl I agree, but that is going to probably require a new RFC as there is currently no way to "configure" socket connection.

I'd also like to see if we can stabilize a set_keepalive function. Not quite the same, but closely related. If it doesn't make sense in this RFC, I can file a new one.

@netvl, @carllerche unfortunately a connection timeout is much more complicated than a socket timeout. The options being bound in this RFC have clear implementations on all platforms and have pretty obvious semantics. Connecting with a timeout, however, involves creating a socket, setting it in nonblocking mode, trying to connect, waiting for it to finish, and then finally setting back to blocking mode before returning it.
Regardless this sort of functionality would definitely be done through a "socket builder" type instead of the current convenience functions to create sockets if it is to be implemented.

@sfackler my personal thought was that because None and Some(Duration::zero()) did the same thing using an Option as an argument was a little misleading. For example some might think that Some(Duration::zero()) could be a method to emulate non-blocking mode (aka time out if there's no data immediately), which isn't what actually happens at the system layer.

:+1: for a Timeout trait.

I've updated the RFC to be more explicit about the socket options, to add getter methods, and to lay out a possible alternative for using Option<Duration> instead. I'm especially eager for feedback on that last point -- otherwise I think there's largely consensus for doing at least this much. (Traits can come later on.)

I discussed this on IRC briefly, but we may want to specify the truncation behavior here of timeouts a bit specially. The duration RFC recommends truncating in all cases, but this means that on Windows when you specify a 5ns timeout you would actually pass down a 0ms timeout, which is then interpreted as an infinite timeout.
I'd personally err on the side of something like:

If the Duration specified is of 0-length, skip the next few steps.
If the Duration specified cannot be exactly specified to the current platform, it is truncated to the largest Duration smaller than the given argument which can be exactly specified.
If this Duration now has a length of 0, the smallest nonzero duration is then specified.

Morally speaking <1ms timeouts on Windows will be rounded up, but all other timeouts will be rounded down. In a sense this kinda makes sense because 0 in this context represents infinity and rounding down to infinity seems odd, so we just do the next best thing!

A Duration of 0 meaning infinite timeout is a bit unfortunate and I think that rust can do better. I believe that in the original RFC, Option<Duration> was suggested. I don't recall why this was not approved, but it seems that it would fix the "duration 0 == infinite" problem.

This round-down approach is pretty backwards, given there’s at least one API that is supposed to take at least specified amount of time.
Timeout of 0 associates to non-blocking operations, rather than infinity to me. So, when you pass timeout of 0, you either get timeout/EWOULDBLOCK error or something useful happens immediately.
For removing timeouts remove_timeout() or set_timeout(None) makes much, much more sense.

@carllerche

I don't recall why this was not approved, but it seems that it would fix the "duration 0 == infinite" problem.

As outlined in the alternative the problem with this approach is that Some(Duration::zero()) is equivalent to "infinite timeout" which may be counter-intuitive.

@nagisa

This round-down approach is pretty backwards, given there’s at least one API that is supposed to take at least specified amount of time.

Another alternative @aturon and I were talking about (which I think was omitted from the alternatives by accident) was to return an error on durations such as this. For example specifying 5ns on windows would return an error. This would also possibly open the door to returning an error on Some(0) if we used Option<Duration> instead.

Just throwing this out there, but: is there any reason we don't define Duration as something like:
enum Duration {
    None,
    Infinite,
    Some(u64),
}

Where Some and None can be changed to names that don't conflict with Option, of course.

@alexcrichton IIRC we discussed only making it an error to send a Some(Duration::zero()), and I think that giving an error for non-zero durations that would happen to round down on specific platforms is much too subtle. I would personally vote for rounding up in this case.
With that said: is there anyone who strongly prefers to take Duration rather than the proposed alternative of Option<Duration> (and returning an invalid input error on zero)? If not, I will switch around the proposals in the RFC.

I have updated the RFC to make Option<Duration> the primary proposal.
The question of rounding for Windows is left as an implementation detail, somewhat dependent on how things work out with Duration in general.
This RFC should be considered to be in its "final comment period" at this point.

I've pushed an update returning Result<Option<Duration>>, but also laying out an alternative enum-based approach that could handle nonblocking support in the same API.

Is this good to merge now? My calculations suggest that this missed the 1.1 train :(

@seanmonstar It's been in it's final comment period for two weeks, so it seems good to me. (We're still getting the subteams fully up and running.)
@alexcrichton thoughts?

Before this lands, I’d really want for set_timeout(Some(Duration::new(0, 0))) mean set_blocking(false) (and of course, opinions on that)

I agree with @aturon that I believe this RFC has baked long enough that this is ready for acceptance. There is broad support for the API proposed here as well as the semantics of what'll happen on Windows and Unix, and the case @nagisa brought up for nonblocking sockets is a backwards-compatible extension that can be made (and the implementations will initially land as #[unstable]). After giving more thought to socket options in general this API also fits quite nicely into the current proposed conventions for further socket options.
As a result, I'm going to merge this and open an issue for tracking the implementation, thanks for the comments everyone!

Not sure where ongoing discussion of this should go, so trying here.
Currently, after setting a timeout, if a read does trigger a timeout, the error returned is e.kind() == WouldBlock. Would it make sense to internally match for WouldBlock, and if a timeout for the current operation has been set, and/or the socket is not in non-blocking mode, translate the error into TimedOut?
/cc @softprops

I considered that during the implementation, but we decided against that under the rationale that it was too magical - io::Error maps directly down to errno and seems a bit weird to change that in random cases. Checking if the socket is in non-blocking mode/has a timeout would each be a system call, which seems like it would violate the "direct bindings" philosophy of the current IO module. For example, a call to TcpStream::read would change from simply a call to libc read to a call to read and then maybe a couple of fnctl calls if the read timed out.
It might make sense to add a method to io::ErrorKind that would match against both WouldBlock and TimedOut to make handling it more straightforward.

Also, it's very possible to take a std::io socket and switch it to non blocking, which would then return WouldBlock when the socket is not ready (vs. a timeout).

It might make sense to add a method to io::ErrorKind that would match against both WouldBlock and TimedOut to make handling it more straightforward.

There was an interesting conditional in a test in the pr that seemed like it hinted at the need for that
https://github.com/rust-lang/rust/pull/25818/files#diff-e1b6aa0742f9015d1840084d1925ece9R941

Are there cases where it would return ETIMEDOUT?
On Mon, Aug 10, 2015, 11:10 AM doug tangren notifications@github.com
wrote:

It might make sense to add a method to io::ErrorKind that would match
against both WouldBlock and TimedOut to make handling it more
straightforward.
There was an interesting conditional in a test in the pr that seemed like
it hinted at the need for that
https://github.com/rust-lang/rust/pull/25818/files#diff-e1b6aa0742f9015d1840084d1925ece9R941
—
Reply to this email directly or view it on GitHub
https://github.com/rust-lang/rfcs/pull/1047#issuecomment-129553513.

@carllerche yea, thus the suggestion of checking if the socket is non-blocking.
@sfackler it wouldn't be the first time that an API was normalized because of OS differences: On Windows, a read return value of -1 will first be checked for WSAESHUTDOWN, to satisfy Rust's API contract of returning Ok(0) at EOF.

authors: alexcrichton andrew-d aturon carllerche l0kod nagisa netvl reem seanmonstar sfackler softprops


text:
Package not found when install rust-mode through Melpa

After added the required info in  ~/.emacs.d/init.el,
and enter
M-x package-install rust-mode
I got the error message:
http://melpa.milkbox.net/packages/rust-mode-20200513.812.el: Not found
Did you guys have similar error message when install?
My rust env is:
➜  ~ cargo --version cargo 1.44.0 (05d080faa 2020-05-06) ➜  ~ rustc --version rustc 1.44.0 (49cae5576 2020-06-01)
Thanks!

Actually I just found the solution:
 M-x package-refresh-contents
and case solved.
Source: stackover flow

source: gharchive/issue

repo: rust-lang/rust-mode

license_type: permissive

license_source: bigquery


text:
Playbot crashes difficult to debug

Right now if any thread in playbot crashes (e.g. panics) then the rest of the connections keep going and the logs have to be hunted through to find the culprit. Perhaps some tweaks could be done to assist this?

For all programs run, debug the name of the channel as well
Kill the entire process whenever a thread panics

Thoughts @jonas-schievink?

If it could catch those panics and render an error page it would make it easier for users to submit bug reports.

@brson I think this is only about rustbot, the IRC bot, not the playpen webserver, but that idea sounds good anyways.
@alexcrichton Agreed. We should also set the name of the threads to the channel they're connected to (we don't do that currently for some reason). Maybe a viable (and very simple) way of implementing the second point would be to use the panic-as-abort machinery (unless I'm missing something).

@jonas-schievink sounds good to me!

On the other hand, we probably don't want to make the playpen webserver DoS-prone by aborting on panics (Iron catches them for us, and there's a few places where wrong user input leads to a panic), and there's no way to make playbot abort on panic and playpen not. I'll make playbot abort in a catch_unwind block instead.

authors: alexcrichton brson jonas-schievink

repo: rust-lang/rust-playpen

license: mit


text:
linfa_bayes show error: records not in row-major layout

  let df =CsvReader::from_path("./510_model_data.csv")
            .unwrap()
            .infer_schema(None)
            .has_header(true)
            .finish()
            .unwrap();
    let df = df.tail(Some(200));
    let col_target = df.column("d_target_high").unwrap();
    let target_high = col_target.f64().unwrap().iter().collect::<Vec<_>>();
    let target: ArrayBase<ndarray::OwnedRepr<_>, _> = ArrayBase::from_vec(target_high.to_vec());
    let mut features = df.clone();
    features = features.drop("d_target_low").unwrap();
    features = features.drop("d_target_high").unwrap();

    for col_name in features.get_column_names_owned(){
        let casted_col = df.column(&col_name).unwrap()
            .cast(&DataType::Float32)
            .expect("Failed to cast column");
        features.with_column(casted_col).unwrap();
    }

    let features_ar = features.to_ndarray::<Float64Type>(IndexOrder::Fortran).unwrap();

    let linfa_dataset = Dataset::new(features_ar,target)
           .map_targets(|x| if *x > Some(2.0) {"red"} else {"green"});
    let (train,valid) = linfa_dataset.split_with_ratio(0.9);
    let model = MultinomialNb::params().fit(&train)?;

thread 'main' panicked at C:\Users\44310.cargo\registry\src\index.crates.io-6f17d22bba15001f\linfa-0.7.0\src\dataset\impl_dataset.rs:946:9:
records not in row-major layout
how to solve it?

let features_ar = features.to_ndarray::<Float64Type>(IndexOrder::C).unwrap();
change to IndexOrder::C，show errors:
thread 'main' panicked at C:\Users\44310.cargo\registry\src\index.crates.io-6f17d22bba15001f\linfa-bayes-0.7.0\src\base_nb.rs:44:32:
called Result::unwrap() on an Err value: UndefinedOrder

repo: rust-ml/linfa

license_source: github-api


text:
Segmentation Fault when assigning a Slot to the "value_changed" socket of a QSpinBox

The problem code:
x.value_changed().connect(&controller.x_changed);
y.value_changed().connect(&controller.y_changed);

x and y are QSpinBoxes, initialized via the following function:
        // macro for creating a spin box
        macro_rules! spinbox {
            ($name: expr) => (
                unsafe {
                    let mut container = QWidget::new_0a();
                    let mut container_layout = QHBoxLayout::new_1a(&mut container).into_ptr();

                    // label and spin box
                    let mut spin_label = QLabel::from_q_string(&QString::from_std_str($name));
                    let mut spin_box = QSpinBox::new_0a();
                    spin_box.set_minimum(-127);
                    spin_box.set_maximum(127);

                    container_layout.add_widget(&mut spin_box);
                    container_layout.add_widget(&mut spin_label);

                    layout.add_widget(&mut container);
                    spin_box.into_ptr()
                }
            )
        }

        let x = spinbox!("X");
        let y = spinbox!("Y");

x_changed and y_changed are initialized via the following macro:
        // macro for creating a slot that corresponds to a spinbox
        macro_rules! changed_handler {
            ($field_name: ident) => {
                unsafe {
                    Slot::new(move || {
                        (*input_reference.lock().unwrap()).$field_name = $field_name.value().try_into().unwrap();
                    })
                }
            }
        };

        let x_changed = changed_handler!(x);
        let y_changed = changed_handler!(y)

input_reference is an Arc<Mutex<a struct of my own creation>> that is passed into this function. For a more complete example, refer to my complete source code here.
The output: This is a Mupen64Plus plugin, so the complete output of that program loaded with this plugin is listed here:
$ mupen64plus --verbose --input target/debug/libtasinput2.so test_rom.n64
 __  __                         __   _  _   ____  _
|  \/  |_   _ _ __   ___ _ __  / /_ | || | |  _ \| |_   _ ___
| |\/| | | | | '_ \ / _ \ '_ \| '_ \| || |_| |_) | | | | / __|
| |  | | |_| | |_) |  __/ | | | (_) |__   _|  __/| | |_| \__ \
|_|  |_|\__,_| .__/ \___|_| |_|\___/   |_| |_|   |_|\__,_|___/
             |_|         http://code.google.com/p/mupen64plus/
Mupen64Plus Console User-Interface Version 2.5.0

UI-Console: attached to core library 'Mupen64Plus Core' version 2.5.0
UI-Console:             Includes support for Dynamic Recompiler.
UI-Console:             Includes support for MIPS r4300 Debugger.
Core: Goodname: Super Mario 64 (U) [!]
Core: Name: SUPER MARIO 64
Core: MD5: 20B854B239203BAF6C961B850A4A51A2
Core: CRC: 635A2BFF 8B022326
Core: Imagetype: .v64 (byteswapped)
Core: Rom size: 8388608 bytes (or 8 Mb or 64 Megabits)
Core: ClockRate = F
Core: Version: 1444
Core: Manufacturer: Nintendo
Core: Cartridge_ID: 4D53
Core: Country: USA
Core: PC = 80246000
Core: Save type: 0
UI-Console Status: Cheat codes disabled.
UI-Console: using Video plugin: 'Mupen64Plus OpenGL Video Plugin by Rice' v2.5.0
UI-Console: Video plugin library: /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-video-rice.so
UI-Console: using Audio plugin: 'Mupen64Plus SDL Audio Plugin' v2.5.0
UI-Console: Audio plugin library: /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-audio-sdl.so
Input Error:
Input Error: Starting input plugin...
Input Error:

UI-Console: using Input plugin: 'TAS Input Plugin 2 by not_a_seagull' v1.0.0
UI-Console: Input plugin library: target/debug/libtasinput2.so
UI-Console: using RSP plugin: 'Hacktarux/Azimer High-Level Emulation RSP Plugin' v2.5.0
UI-Console: RSP plugin library: /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-rsp-hle.so
Core: input plugin did not specify a render callback; there will be no on screen display by the input plugin.
Core: Memory initialized
Video: Reading .ini file: RiceVideoLinux.ini
Video: SSE processing enabled.
Video: Found ROM 'SUPER MARIO 64', CRC ff2b5a632623028b-45
Video: InitExternalTextures
Video: Initializing OpenGL Device Context.
Video: Initializing video subsystem...
Core: Setting 32-bit video mode: 320x240
Input Error:
Input Error: Spin boxes
Input Error:

[1]    6817 segmentation fault (core dumped)  mupen64plus --verbose --input target/debug/libtasinput2.so

The problem could be the ArcMutex dereferenced in the socket, but I'm relatively sure it isn't.

The real issue here was that I was not initializing the spin boxes properly.

repo: rust-qt/ritual


text:
Fix #107 by switching to proc_macro2::Span

Issue caused by incorrect use of a private method of upstream
syn::export::Span.
With the commit
https://github.com/dtolnay/syn/commit/957840eba2c7f11c95e0227760d78dc481a91de7
syn has further removed from the public API the export private
interface, and thus the Span.
However, Span in sys was re-exported from crate proc_macro2.
The fix imports Span straight from proc_macro2 without sys
intermediation.

Exactly what i needed
Looking forward to merging

source: gharchive/pull-request

authors: Heavenston davidedelpapa


text:
vsock: Set VhostUserProtocolFeatures::MQ

As per the vhost-user specification:
"Back-ends should always implement the VHOST_USER_PROTOCOL_F_MQ protocol feature, even for devices with a fixed number of virtqueues, since it is simple to implement and offers a degree of introspection."
Vsock backend support three virtqueues and hence this should be set.
Summary of the PR
Please summarize here why the changes in this PR are needed.
Requirements
Before submitting your PR, please make sure you addressed the following
requirements:

[ ] All commits in this PR have Signed-Off-By trailers (with
git commit -s), and the commit message has max 60 characters for the
summary and max 75 characters for each description line.
[ ] All added/changed functionality has a corresponding unit/integration
test.
[ ] All added/changed public-facing functionality has entries in the "Upcoming
Release" section of CHANGELOG.md (if no such section exists, please create one).
[ ] Any newly added unsafe code is properly documented.

LGTM!
@vireshk the audit warning is fixed in the current main, so I guess a rebase should fix it.

@epilys thanks for the changelog entry!

authors: stefano-garzarella vireshk

repo: rust-vmm/vhost-device


text:
How to send multiple http requests with surf & async-std ?

Hello,
How can I send N http requests with at most m TCP connections (to limit file descriptors) with surf & async-std ?
I imagined something like:
let urls: Vec<String> = ...;
let client = surf::Client::new();

stream::???(urls)
    .map(GET with client)
    .limit(m);

(I read surf & async-std docs but still don't know how to do it.)

You can send concurrent HTTP requests by using futures::future::join_all, e.g.
let urls = vec![
    "https://httpbin.org/get",
    "https://httpbin.org/get",
    "https://httpbin.org/get",
    "https://httpbin.org/get",
    "https://httpbin.org/get",
    "https://httpbin.org/get",
    "https://httpbin.org/get",
    "https://httpbin.org/get",
    "https://httpbin.org/get",
    "https://httpbin.org/get",
];
futures::future::join_all(urls.iter().map(|url| surf::get(url))).await

To limit this to N number of requests you can use chunks, e.g.
for chunk in urls.chunks(2) {
    futures::future::join_all(chunk.iter().map(|url| surf::get(url))).await
}

This seems to be resolved; going to go ahead and close it!

@liamcurry Thank you very much :)

authors: fukuang liamcurry yoshuawuyts

repo: rustasync/surf


text:
How to derive typescript definitions directly from structs?

I'm trying to generate typescript definitions for parameters, which are directly derived from my actual structs.
struct Foo {
    pub my_id: String,
}

pub async fn foo(pars: Foo) -> Result<JsValue, JsValue> {
    todo!()
}

Expected generated code:
/**
* @param {Foo} pars
* @returns {Promise<any>}
*/
export function foo(pars: Foo): Promise<any>;

export interface Foo {
  my_id: string
}

So far I found typescript_custom_section, but I don't understand how to do this:

The proc_derive_macro "MyTypescriptExport" can export its own #[wasm_bindgen(typescript_custom_section)] section, which would then be picked up by wasm-bindgen-cli

Is there an example or crate somewhere?
There's the rust-typescript-type-def crate, which can be used to generate the typescript definitions. But it's unclear how to wire the wasm-bindgen declarations with these types. Everything I attempted ends generating and referencing a separate definition.
typescript_type generates code as above, But then I've to define an empty type in Rust and parse it manually to the actual struct. I attempted using it on the actual struct, marking the fields with skip(), but this generated separate definitions:
export interface Foo {
  my_id: string
}

export class Foo {
  free(): void;
}

I could export the struct only normally (which would generate the second definition, with all the fields), but then if I understand correctly, I've to manage memory manually, which is not wanted.

Ok, I went through a proc macro tutorial and put this together: https://github.com/ivanschuetz/export_ts_macro
Appreciate feedback - is that the right direction? if yes, how to improve it? if not, what to do instead?

Someone recommended tsify to me, which solves this - so I'm closing this.

repo: rustwasm/wasm-bindgen


text:
Best way to handle self-consuming content

I've been working on replacing some JavaScript hashing code with Rust variants. This works great as a simple function and the performance numbers look pretty good compared to asmCrypto.js, not to mention the ease of adding support for additional algorithms:
#[wasm_bindgen]
pub fn sha2_256(input_bytes: &[u8]) -> String {
    use sha2::Digest;

    let mut hasher = Sha256::default();

    hasher.input(input_bytes);
    let output = hasher.result();
    return format!("{:x}", output);
}

Unfortunately, adding a streaming interface hits a couple of implementation issues because the sha2 crate (and the rest of the RustCrypto hash implementations) make Digest.result() self-consuming:
#[wasm_bindgen]
pub struct Sha2_256Hasher {
    hasher: Sha256,
}

#[wasm_bindgen]
impl Sha2_256Hasher {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Sha2_256Hasher {
        Sha2_256Hasher {
            hasher: Sha256::default(),
        }
    }

    pub fn update(&mut self, input_bytes: &[u8]) {
        self.hasher.input(input_bytes)
    }

    pub fn hex_digest(&mut self) -> String {
        let output = self.hasher.result();  # FAIL: cannot move out of borrowed content
        return format!("{:x}", output);
    }
}

I won't pretend to be a Rust expert but normally I'd just remove the & for hex_digest but wasm-bindgen currently returns an error “by-value self not yet supported”.
Is there a better way to cleanly solve this kind of problem? I was thinking initially about passing in a JavaScript callback or generator but that doesn't appear to be supported yet and doing it by passing Rust closures looks like it'll be messy.

Thanks for the report! Here we'll likely just want to add support for self as it should have a simple-enough translation to JS. In that sense I think for now you can work around this with an internal Option and otherwise this is a TODO for wasm-bindgen to implement!

Thanks for confirming that I wasn't missing something obvious. The experience has otherwise been pretty awesome, with a substantial performance win over asmCrypto.js!

Hi, I also have the same issue in my project.
My solution is to implement the self-consuming method as a non-member function. For your example it could be:
#[wasm_bindgen]
pub fn sha2_256Hasher_hex_digest(self_: Sha2_256Hasher) -> String {
    // replace self with self_
}

Then you can pass your object to this function as an argument.  Notice that the member ptr of the consumed object on JS side will be set to 0. Make sure that you won't use it after passing to this function.

I ended up kludging this with a Cell in https://github.com/acdha/wasm-hashing/commit/6bb246dd7b1ab420aeacc8031a787b4df238002c which is ugly (I wanted to see if there was a cleaner generic way to handle that boilerplate, although trait impls appear not to be supported yet) but was enough to confirm that I'm getting competitive performance with other hash implementations. I need to review that code but my main priority now is testing it using File contents in a web worker since it appears to be quite a bit faster than what I've been using or even the browser-native SubtleCrypto interface, which seems surprising.

@alexcrichton I just picked this project up again and wanted to see if my original code would work (e.g. using pub fn hex_digest(self) -> String) using wasm-bindgen 0.2.15. It compiles but webpack fails with this error:
ERROR in ./wasm_hashing.js 430:14
Module parse failed: Identifier 'ptr' has already been declared (430:14)
You may need an appropriate loader to handle this file type.
|         wasm.sha2_256hasher_hex_digest(retptr, ptr);
|         const mem = getUint32Memory();
>         const ptr = mem[retptr / 4];
|         const len = mem[retptr / 4 + 1];
|
 @ ./index.js 8:19-43

Oh dear, sounds bad! That should be fixed in https://github.com/rustwasm/wasm-bindgen/pull/662

Thanks for the rapid response!

authors: acdha alexcrichton jevancc


text:
expose forget to wasm

Closes #1543
I made some research on the issue
forget is exposed here:
https://github.com/rustwasm/wasm-bindgen/blob/master/crates/cli-support/src/js/mod.rs#L792
Then there is a line if contents.starts_with("function") { here
https://github.com/rustwasm/wasm-bindgen/blob/master/crates/cli-support/src/js/mod.rs#L229
Well, it's not a class and not a function, that's why we go here:
https://github.com/rustwasm/wasm-bindgen/blob/master/crates/cli-support/src/js/mod.rs#L252
Probably, exposing to wasm every exported const is not the best idea, but it depends on the usage. If only function aliases are bound in such way, it's fine enough.

Looks great to me, thanks @ibaryshnikov!

authors: alexcrichton ibaryshnikov


text:
Slow compile times

It seems that something is causing excessively slow compile times. For instance, adding a simple println! costs nearly 40 seconds to recompile:
$ cargo run --database-url ...
   Compiling warp-api-starter-template v0.1.0 (/Users/max/Repositories/warp-api-starter-template)
    Finished dev [unoptimized + debuginfo] target(s) in 39.35s
     Running `target/debug/warp-api-starter-template`

Where the only change is:
diff --git a/src/environment/argon.rs b/src/environment/argon.rs
index b70bcd5..ce58cc9 100644
--- a/src/environment/argon.rs
+++ b/src/environment/argon.rs
@@ -15,6 +15,7 @@ impl Argon {
             argon_iterations,
             ..
         } = args;
+        println!("foo");
         Self {
             secret: argon_secret.to_owned(),
             memory_size: argon_memory_size.to_owned(),

This is actually decently faster than other compile times I've observed, which sometimes exceed two minutes (!) but are not significant changes.
Depending on your development style, this may be a showstopper.

Any recommendations on improving the compile times are welcome.

#12 might help in the case of slow compile times. Rust considers crate as a compilation unit and ATM warp-api-starter-template is huge crate and spliting it into multiple dependent crate might allow for better compile times. This is not tested notion for me. I need to try it out and see.

@aslamplr I think you're right that breaking things up into component crates could help. At the very least, it should avoid to always recompile everything.

authors: aslamplr maxcountryman

repo: rusty-crab/warp-api-starter-template

license: MIT