BehindTheBarrier

joined 1 year ago
[–] [email protected] 18 points 6 months ago (1 children)

Assuming digital button here.

Like how a lot of sites, link to Facebook, insta, X, etc at the bottom of their web page. Just the fact it was an option meant something.

[–] [email protected] 1 points 6 months ago

Python, C#, Rust

Used a bit of C++ and Matlab, but saying I know them is a stretch really.

[–] [email protected] 6 points 6 months ago (2 children)

I'm in the MPC-HC gang on Windows. Just so much more practical than other players. The main selling point was that full-screen the controls go away once you move the cursor off them, it was amazing. And no waiting for subs to be processed like VLC had to back then, never turned back so don't know if that is still a thing.

[–] [email protected] 47 points 6 months ago (4 children)

Not to completely spring to IKEAs defense here, but I heard they really were affected by production and shipping problems during covid. It's reasonable prices would go up, and at least good that they are going down again.

[–] [email protected] 0 points 6 months ago* (last edited 6 months ago) (1 children)

At least LCD is mostly temporary according to that article.

But pixels do degrade over time, not sure if it counts as burn-in though.

[–] [email protected] 2 points 7 months ago (1 children)

Given your little driving, sticking with the old one is a sound decision. But it's worth looking into getting a used electric car if you do need to upgrade. Especially since you say you don't use the car too much, an older one which has had some battery decay might still be fully operable, and closer to a price range where it's not a large monetary loss.

[–] [email protected] 2 points 7 months ago* (last edited 7 months ago)

Ah, so I'm actually cheating with the pointer reading, i'm actually making a clone of Arc without using the clone()... And then dropping it to kill the data. I had assumed it just gave me that object so I could use it. I saw other double buffer implementations (aka write one place, read from another palce, and then swap them safely) use arrays with double values, but I wasn't much of a fan of that. There is some other ideas of lock free swapping, using index and options, but it seemed less clean. So RwLock is simplest.

And yeah, if I wanted a simple blog, single files or const strings would do. But that is boring! I mentioned in the other reply, but it's purely for fun and learning. And then it needs all the bells and whistles. Writing html is awful, so I write markdown files and use a crate to convert it to html, and along the way replace image links with lazy loading versions that don't load until scrolled down to. Why, because I can! Now it just loads from files but if I bother later i'll cache them in memory and add file watching to replace the cached version. Aka an idea of the issue here.

[–] [email protected] 2 points 7 months ago* (last edited 7 months ago) (1 children)

Thanks for the great reply! (And sorry for that other complicated question... )

Knowing that &str is just a reference, makes sense when they are limited to compile time. The compiler naturally knows in that case when it's no longer used and can drop the string at the appropriate time. Or never dropped in my case, since it's const.

Since I'm reading files to serve webpages, I will need Strings. I just didn't get far enough to learn that yet.... and with that 'Cow' might be a good solution to having both. Just for a bit of extra performance when some const pages are used a lot.

For example code, here's a function. Simply take a page, and constructs html from a template, where my endpoint is used in it.

pub fn get_full_page(&self, page: &Page) -> String {
        self.handler
            .render(
                PageType::Root.as_str(),
                &json!({"content-target": &page.endpoint}),
            )
            .unwrap_or_else(|err| err.to_string())
    }

Extra redundant context: All this is part of a blog I'm making from scratch. For fun and learning Rust, and Htmx on the browser side. It's been fun finding out how to lazy load images, my site is essentially a single paged application until you use "back" or refresh the page. The main content part of the page is just replaced when you click a "link". So the above function is a "full serve" of my page. Partial serving isn't implemented using the Page structs yet. It just servers files at the moment. When the body is included, which would be the case for partial serves i'll run into that &str issue.

[–] [email protected] 2 points 7 months ago (2 children)

Sorry, but a long and slightly complicated question, for a hypotetical case.

I wanted to serve pages in my blog. The blog doesn't actually exist yet (but works locally, need to find out how I can safely host it later...), but lets assume it becomes viral, and by viral i mean the entire internet has decided to use it. And they are all crazy picky about loading times....

I haven't figued out the structure of the Page objects yet, but for the question they can be like the last question:

#[derive(Clone)]
pub struct Page<'a> {
    pub title: &'a str,
    pub endpoint: &'a str,
}

I wanted to create a HashMap that held all my pages, and when I updated a source file, the a thread would replace that page in the mapping. It's rather trivial of a problem really. I didnt find out if I could update a mapping from a thread, so I decided to make each value something that could hould a page and have the page object replaced on demand. It made somewhat sense since I don't need to delete a page.

There is a trivial solution. And it's just to have each HashMap value be a RwLock with an Arc holding my large string. No lagre string copies, Arc make it shared, and RwLock is fine since any number of readers can exist. Only when writing is the readers locked. Good enough really.

But I heard about DoubleBuffers, and though, why can't I have a AtomicPointer to my data that always exist? Some work later and I had something holding an AtomicPointer with a reference to an Arc with my Page type. But it didn't work. It actually failed rather confusingly. It crashed as I was trying to read the title on my Page object after getting it from the Arc. It wasn't even any thread stuff going on, reading once works, the next time it crashed.

struct SharedPointer<T> {
    data: AtomicPtr<Arc<T>>,
}

impl<T> SharedPointer<T> {
    pub fn new(initial_value: T) -> SharedPointer<T> {
        SharedPointer {
            data: AtomicPtr::new(&mut Arc::new(initial_value)),
        }
    }

    pub fn read(&self) -> Arc<T> {
        unsafe { self.data.load(Relaxed).read_unaligned() }.clone()
    }

    pub fn swap(&self, new_value: T) {
        self.data.store(&mut Arc::new(new_value), Relaxed)
    }
}

#[test]
pub fn test_swapping_works_2() {
    let page2: Page = Page::new("test2", "/test2");
    let page: Page = Page::new("test", "/test");
    let entry: SharedPointer<Page> = SharedPointer::new(page.clone());

    let mut value = entry.read();

    assert_eq!(value.title, page.title);
    value = entry.read();
    assert_eq!(value.title, page.title);

    entry.swap(page2.clone());

    let value2 = entry.read();
    assert_eq!(value2.title, page2.title);
    assert_eq!(value.title, page.title);
}

This has undefined behavior, which isn't too surprising since I don't understand pointers that much... and I'm actually calling unsafe code. I have heard it can produce unexpected error outside it's block. I'm just surprised it works a little. This code sometimes fails the second assert with an empty string, crashes with access violation, or one time it gave me a comparison where some of it was lots of question marks! My best understanding is that my Page or it's content is moved or deallocated, but odd that my Arc seems perfectly fine. I just don't see the connection between the pointer and Arcs content causing a crash.

I may just be doing the entire thing wrong, so sticking with RwLock is much better and safer since there is no unsafe code. But I seek to know why this is so bad in the first place. What is wrong here, and is there a remedy? Or is it just fundamentally wrong?

[–] [email protected] 2 points 7 months ago (3 children)

Hi,

Learning Rust and getting caught up in details, but I always want to know the whys of things, and the minor differences.

Lets start of with, is there a difference between the const value vs const reference?

// Given this little struct of mine, a Page with information about an endpoint
#[derive(Clone)]
pub struct Page<'a> {
    pub title: &'a str,
    pub endpoint: &'a str,
}

// Value
const ROOT_PAGE: Page = Page::new("Home", "/home");

// Reference
const ROOT_PAGE: &'static Page = &Page::new("Home", "/home");
  1. Since my functions always take a reference, is there any advantage to any of them. References are read-only, but since it's const it probably doesn't matter. What is prefered?

  2. I know String does allocations, while &str is a string slice or something which may be on the stack. Do I not end up making any allocations in this case since stucts are on the stack by default, and only hold the pointers to a string "slice". Especially given how they are made in this case.

  3. Is structs with references like this okay, this Page is constant but I'm going to make many "Pages" later based on the pages my blog has, as well as some other endpoints of course.

  4. If the struct is cloned, is the entire string as well, or just the pointer to the string slice? I assume it does copy the entire string, since to the best of my knowledge a &str does not do any reference counting, so deleting a &str means deleting it's content, not just the reference. Since that is the case, a clone will also copy the string.

  5. I am contemplating adding a "body" string to my Page struct. These string will of course be large and vary depending on the page. Naturally, I do not want to end up copying the entire body string every time the Page is cloned. What is the best course here, it kind of depends on the previous question, but is an Arc the solution here? There is only reading to be done from them, so I do not need to worry about any owner holding it.

[–] [email protected] 2 points 7 months ago

The peak might be higher for induction.

Not in the US, so electrical grid is different but induction on boost can use much more wattage for short periods, triggering the breaker. In my case the circuit was 16A if I remember correctly while a powerful induction should be on 25A.

[–] [email protected] 8 points 7 months ago

Reminds me of folding cardboard boxes. If you are taking a flat piece and make a box of it, are you folding a box or unfolding the cardboard. Or both. And when you do the reverse, you do the same, do you not?

view more: ‹ prev next ›