These are chat archives for rust-lang/rust

30th
Oct 2018
Max Frai
@max-frai
Oct 30 2018 01:06
Nightly is broken?
trsh
@trsh
Oct 30 2018 08:53
the trait bound `std::vec::Vec<u8>: futures::Future` is not satisfied
   --> manu/src/applications/api/views/shopify_invoice.rs:190:14
    |
190 |             .and_then(move |c| match c {
    |              ^^^^^^^^ the trait `futures::Future` is not implemented for `std::vec::Vec<u8>`
So I can't return vec u8 from a future?
Paul Masurel
@fulmicoton
Oct 30 2018 08:55
This just tells you Vec<u8> itself is not a future
trsh
@trsh
Oct 30 2018 09:01
Ok, yes
It was so
tnx
trsh
@trsh
Oct 30 2018 11:07
What was the Mutex single thread alternative?
trsh
@trsh
Oct 30 2018 11:25
NM
Another question. What does this error really mean cannot move out of static item
?
Denis Lisov
@tanriol
Oct 30 2018 11:26
If there were a value in a static that you moved out, it would be left in an invalid state, which is not allowed.
trsh
@trsh
Oct 30 2018 11:34
@tanriol
let mut print: Vec<u8> = vec![];
  //let mut pdf_app = PdfApplication::new().expect("Failed to init PDF application");

  unsafe {
    INIT_PDF_APP.call_once(move || {
      PDF_APP = Some(PdfApplication::new().expect("Failed to init PDF application"));
    });

    let _res = PDF_APP.unwrap() // TODO: result
    .builder()
    .orientation(Orientation::Portrait)
    .margin(Size::Inches(1))
    .title("Invoice")
    .build_from_html(&tmpl_body)
    .expect("failed to build pdf")
    .read_to_end(&mut print);

    print
  }
Where the "moving out" ?
Denis Lisov
@tanriol
Oct 30 2018 11:36
I'd guess it's the final print
trsh
@trsh
Oct 30 2018 11:37
@tanriol maybe u can suggest a fix?
Vladislav
@vmarkushin
Oct 30 2018 11:38
What is PDF_APP?
trsh
@trsh
Oct 30 2018 11:38
static mut PDF_APP: Option<PdfApplication> = None;
Vladislav
@vmarkushin
Oct 30 2018 11:40
You are moving it into the closure on 5th line
Denis Lisov
@tanriol
Oct 30 2018 11:40
Yeah, I was wrong. This is some weird code.
Especially the big unsafe block.
Why not lazy_static for initialization?
trsh
@trsh
Oct 30 2018 11:46
@tanriol lazy_static cries about unsafe between threads
@NEGIhere hmm
Denis Lisov
@tanriol
Oct 30 2018 11:49
Don't see anything about likely threading problems in their documentation.
Im replicating the code
fn get_cached_pdf_app() -> Option<PdfApplication> {
  unsafe {
    INIT_PDF_APP.call_once(|| {
      PDF_APP = Some(PdfApplication::new().expect("Failed to init PDF application"));
    });
    PDF_APP // Here the error
  }
}
Denis Lisov
@tanriol
Oct 30 2018 11:55
Don't test these errors with usize. It implements Copy, so it can be just copied unlike the objects you deal with.
trsh
@trsh
Oct 30 2018 12:01
26 | / lazy_static! {
27 | |     static ref PDF_APP2: PdfApplication = PdfApplication::new().expect("Failed to init PDF application");
28 | | }
   | |_^ `*const ()` cannot be shared between threads safely
   |
   = help: within `applications::api::views::shopify_invoice::wkhtmltopdf::PdfApplication`, the trait `std::marker::Sync` is not implemented for `*const ()`
   = note: required because it appears within the type `std::marker::PhantomData<*const ()>`
   = note: required because it appears within the type `applications::api::views::shopify_invoice::wkhtmltopdf::lowlevel::PdfGuard`
   = note: required because it appears within the type `applications::api::views::shopify_invoice::wkhtmltopdf::PdfApplication`
   = note: required by `lazy_static::lazy::Lazy`
This is sweet. The doc says PdfApplication must be inited once per process, but in same time it has all doors closed
Denis Lisov
@tanriol
Oct 30 2018 12:05
This looks like a safety check. Are you sure PdfApplication should be thread-safe?
Dmitriy
@dpogretskiy
Oct 30 2018 12:05
use mpcs channels and a thread
it most certainly is not threadsafe
trsh
@trsh
Oct 30 2018 12:05
@tanriol it must be on single, same thread
Dmitriy
@dpogretskiy
Oct 30 2018 12:06
then it can't be static, and probably should be mutable to work
trsh
@trsh
Oct 30 2018 12:06
use mpcs channels and a thread
Can give more insight?
Denis Lisov
@tanriol
Oct 30 2018 12:07
@trsh Do you use one thread or multiple?
Dmitriy
@dpogretskiy
Oct 30 2018 12:07
something similar to actor model
if you use single thread anyway you can probably use threadlocal, but if you don't it will break stuff
trsh
@trsh
Oct 30 2018 12:08
@tanriol im on actix-web, and I think it uses multiple threads
when dealing with requests
so its a problem
Kelly Thomas Kline
@kellytk
Oct 30 2018 12:09
How can I remedy the error "unused futures::MapErr that must be used"? I've read https://docs.rs/futures/0.2.0/futures/future/struct.MapErr.html but there's no discussion of using it or how to do so
Dmitriy
@dpogretskiy
Oct 30 2018 12:09
yeah it certainly does
@kellytk that's a good one
trsh
@trsh
Oct 30 2018 12:10
So maybe I should create a new thread specially for that PdfApp
Dmitriy
@dpogretskiy
Oct 30 2018 12:10
MapErr is type that wraps another future
trsh
@trsh
Oct 30 2018 12:10
No Idea how todo that
Denis Lisov
@tanriol
Oct 30 2018 12:10
@kellytk This one means that you create a Future, but never actually run or spawn it so it does nothing.
Dmitriy
@dpogretskiy
Oct 30 2018 12:10
so type futures::MapErr is just a buzz
you just ignore future all together, and you probably should not
Kelly Thomas Kline
@kellytk
Oct 30 2018 12:11
Thanks I'll take another look
Dmitriy
@dpogretskiy
Oct 30 2018 12:13
@trsh you can use something like thread bound actor and threadlocal PdfApplication, but it's just a theory, it would work in say Scala, but i don't know about actix, gotta check out
trsh
@trsh
Oct 30 2018 12:19
Will try something
Dmitriy
@dpogretskiy
Oct 30 2018 12:26
yeah, there is no such thing i think, never found something like that, but if actor can process one message at a time then threadlocal may or may not work as desired
this might be something to look into https://actix.rs/actix/actix/sync/struct.SyncArbiter.html
trsh
@trsh
Oct 30 2018 12:27
Thats what im trying out
trsh
@trsh
Oct 30 2018 12:58
FAIL!
trsh
@trsh
Oct 30 2018 13:34
So @dpogretskiy what was your proposal with mem and stuff?
let addr = SyncArbiter::start(1, move || PdfAppExecutor);

  let processing = addr
    .send(PdfApp(tmpl_body))
    .map_err(|e| vec![e.to_string()])
    .and_then(|res| match res {
      Ok(v) => Ok(v),
      Err(_) => Ok(vec![]),
    });
This should in theory work, as SyncArbiterexecutes handler in new thread.. but it same problem
trsh
@trsh
Oct 30 2018 14:32
I think there is a diff between thread and process.
trsh
@trsh
Oct 30 2018 15:19
let command_str = format!("echo '{}' | wkhtmltopdf", tmpl_body);
  let mut child = Command::new(command_str)
    .arg("-q")
    .arg("-")
    .arg("-")
    .output()
    .expect("failed to execute process");
So this doesn't work, because the command is somehave parsed?
trsh
@trsh
Oct 30 2018 15:44
Cant get this command working
James McCoy
@jamessan
Oct 30 2018 16:06
echo '{}' | wkhtmltopdf isn't the name of a command. It's something that a shell can interpret and run.
See the first example for how to run something in a shell (the else branch)
but then you'll have to make sure that tmpl_body is properly shell-escaped
James McCoy
@jamessan
Oct 30 2018 16:17
Seems like the better approach would be to write tmpl_body directly to the stdin of the process
trsh
@trsh
Oct 30 2018 16:18
@jamessan something like this:?
let mut child = Command::new("sh")
    .arg("-c")
    .arg("echo")
    .arg(format!("'{}'", tmpl_body))
    .arg("|")
    .arg("wkhtmltopdf")
    .arg("-q")
    .arg("-")
    .arg("-")
    .output()
    .expect("failed to execute process");
James McCoy
@jamessan
Oct 30 2018 16:20
no, .arg(format!("echo '{}' | wkhtmltopdf -q - -", tmpl_body)) since that's a single argument to the sh process.
but, like I said, then you run into the problem of properly shell-escpaing tmpl_body. You completely avoid that problem if you directly execute wkhtmltopdf and write tmpl_body to its stdin
trsh
@trsh
Oct 30 2018 16:22
@jamessan didn't understand from the docs, how to use stdin
James McCoy
@jamessan
Oct 30 2018 16:23
trsh
@trsh
Oct 30 2018 16:24
Ok thanks, will play with that
James McCoy
@jamessan
Oct 30 2018 16:27
Although https://stackoverflow.com/a/37201466/198244 more robustly handles writing to stdin/reading from stdout while avoiding potential deadlocks and points out https://crates.io/crates/subprocess-communicate