How can I start to train with self play?

How can I start to train chess without any data?
run Player, Trainer, Evaluator simultaneously so that run 3 processes same time or sequentially so  that run 1 process any time?
If I need to run simultaneously, how can process data synchronize?

Yes, you have to run simultaneously 3 python scripts:
python src/chess_zero/run.py self
python src/chess_zero/run.py opt
python src/chess_zero/run.py eval

"If I need to run simultaneously, how can process data synchronize?"
All the synchronization is due to the use of Keras saved model files (weights and configuration). The workers 'opt' and 'self' in each iteration always read the "best model" file, and the 'eval' worker is the one in charge to evaluate each next generation model (created by 'opt') against the "best model". If next generation model play better it becomes the new "best model" and so on.
Indeed, DeepMind used an very similar approximation to an evolutionary algorithm with selection by tournament.
Regards.


No file/folder found for package langchain-monorepo

Checked other resources

[X] I added a very descriptive title to this issue.
[X] I searched the LangChain documentation with the integrated search.
[X] I used the GitHub search to find a similar question and didn't find it.

Example Code
none
Description
In the HOME directory of the langchain source code, execute the following command:
poetry install --with lint,typing,test
However, the following errors are thrown, and I have a few questions to ask:
(1) Why do we need to perform a downgrade operation on modules like langchain-core, and how to avoid downgrading?
(2) Why can't the module langchain-monorepo be found?
(3) How to compile the source code of langchain in order to understand the principles of langchain and contribute code to langchain?
My development environment:
Python: Built on conda, Python version 3.8.18
Langchain: The master branch on GitHub.
Error message:
(langchain) [xiaobai@xiaobai langchain-master]$ poetry install --with lint,typing,test
Installing dependencies from lock file
Package operations: 0 installs, 4 updates, 0 removals
• Downgrading langchain-core (0.1.10 /home/xiaobai/data/pro/python/langchain-master/libs/core -> 0.1.3 /home/xiaobai/data/pro/python/langchain-master/libs/core)
• Downgrading langchain-community (0.0.12 /home/xiaobai/data/pro/python/langchain-master/libs/community -> 0.0.6 /home/xiaobai/data/pro/python/langchain-master/libs/community)
• Downgrading langchain (0.1.0 /home/xiaobai/data/pro/python/langchain-master/libs/langchain -> 0.0.352 /home/xiaobai/data/pro/python/langchain-master/libs/langchain)
• Downgrading langchain-experimental (0.0.49 /home/xiaobai/data/pro/python/langchain-master/libs/experimental -> 0.0.47 /home/xiaobai/data/pro/python/langchain-master/libs/experimental)
Installing the current project: langchain-monorepo (0.0.1)
The current project could not be installed: No file/folder found for package langchain-monorepo
If you do not want to install the current project use --no-root
System Info
Python: Built on conda, Python version 3.8.18
Langchain: The master branch on GitHub.
Related Components

[ ] LLMs/Chat Models
[ ] Embedding Models
[ ] Prompts / Prompt Templates / Prompt Selectors
[ ] Output Parsers
[ ] Document Loaders
[ ] Vector Stores / Retrievers
[ ] Memory
[ ] Agents / Agent Executors
[ ] Tools / Toolkits
[ ] Chains
[ ] Callbacks/Tracing
[ ] Async

Boosting because I'm running into the same issue. Using poetry v1.7.1.

Same here


Fixed linting and made service executable

Looks good - if the whole thing passes linting maybe add the linting step to the Jenkins pipeline?


Switch from LGPL-2.1 license to BSD 3-Clause license

Discussing with @DanielePucci we noticed that the repo has the wrong License this PR fixes it switching from LGPL-2.1 to BSD 3-Clause

Thank you! Merging!


Metadata field not properly deserialized when using async_mode=True with PGVector

When using the PGVector class with async_mode=True, the metadata field of the Document objects returned from query methods (e.g., asimilarity_search_with_score_by_vector) is not deserialized into a Python dict. Instead, it remains as a Fragment object or another non-dict type. This causes a ValidationError when the Document class expects metadata to be a dictionary.
To Reproduce
Steps to reproduce the behavior:

Initialize PGVector with async_mode=True and use_jsonb=True.
Add documents to the vector store with metadata.
Perform an asynchronous similarity search, e.g., asimilarity_search or asimilarity_search_with_score_by_vector.
Observe that the returned Document objects have metadata fields that are not dictionaries.

Expected behavior
The metadata field of the returned Document objects should be properly deserialized into Python dictionaries, matching the behavior when async_mode=False.
Actual behavior
When async_mode=True, the metadata field is a Fragment object (from asyncpg), leading to errors when the code expects a dict.
Error message
ValidationError: 1 validation error for Document
metadata
  Input should be a valid dictionary [type=dict_type, input_value=Fragment(buf=b'{"user_id": "ahmed"}'), input_type=Fragment]

Environment:

langchain_postgres version: 0.0.12
Python version: 10,11,12
Database: PostgreSQL with pgvector extension
Async driver: asyncpg

Additional context
This issue arises because asyncpg returns JSONB fields as Record or Fragment objects, which are not automatically deserialized into Python dictionaries by SQLAlchemy when using asynchronous sessions.
Code to Reproduce
Ensure that the required connection details like connection_string, collection_name, and embedding_model are securely provided when testing the code.
from langchain_postgres.vectorstores import PGVector

# Setup the connection to PGVector
connection_string = 'your_connection_string_here'
collection_name = 'your_collection_name_here'
embedding_model = 'your_embedding_model_here'

# Initialize PGVector with the necessary parameters
vstore = PGVector(
    connection=connection_string,
    collection_name=collection_name,
    embeddings=embedding_model,
    use_jsonb=True,
    pre_delete_collection=False,
    async_mode=True  # Set to True to reproduce the issue
)

# Add a document with metadata
vstore.add_document({"user_id": "ahmed"}, metadata={"data": "example"})

# Perform an asynchronous similarity search
result = vstore.asimilarity_search_with_score_by_vector()
print(result.metadata)  # The issue: metadata is not returned as a dictionary

Proposed Solution
Modify the _results_to_docs_and_scores method in the PGVector class to ensure that the metadata field is correctly converted into a dictionary before creating the Document objects.
Related Issues:
#118

Did you fix it? I have related issue: https://github.com/langchain-ai/langchain/issues/28029

Did you fix it? I have related issue: langchain-ai/langchain#28029

already fixed in
https://github.com/langchain-ai/langchain-postgres/pull/125


wayland: only remove libwayland-egl if not using vc4graphics, e.g. when using userland

Related to PR #247.

Sorry, made a mistake in the commit log, now is fine.


Pyannote fails to detect segments correctly

Sorry, while experimenting some real world scenerios with example

Even though “6_speakers.wav” works, for example a very simple “wget https://github.com/thewh1teagle/sherpa-rs/releases/download/v0.1.0/motivation.wav -O motivation.wav” gives the following output:
Running target/debug/examples/infinite motivation.wav
start = 7.52, end = 9.12, speaker = 1
cargo run --example infinite motivation.wav This gives exactly the same result ("start_7.52_end_9.12.wav") I don't understand why it behaves like that :(

I've been experimenting with it to understand behavior, the code below works for most cases. However, when I try a 9 minute audio recording, it gives an error after a while
start = 441.70, end = 443.24, speaker = 19
Processing segment: 443.29s - 448.51s (duration: 5.22s, samples: 167130)
start = 443.29, end = 448.51, speaker = 10
Processing window 46/59 (450.00s to 460.00s)
  Processing tensor of shape: [1, 1182, 7]
  Speech ended at 448.81s
  Speech started at 449.17s
Processing segment: 448.80s - 448.81s (duration: 0.01s, samples: 270)
thread 'main' panicked at examples/infinite.rs:25:10:
called `Result::unwrap()` on an `Err` value: The frames array is empty. No features to compute.

Location:
crates/knf-rs/src/lib.rs:38:9
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
code that works on many cases like motivation.wav and some other test audio files that I have. Note that, this is very ugly and includes many debugging steps to sanity checks :-D
pub fn get_segments<P: AsRef<Path>>(
    samples: &[i16],
    sample_rate: u32,
    model_path: P,
) -> Result<impl Iterator<Item = Result<Segment>> + '_> {
    let session = session::create_session(model_path.as_ref())?;
    let frame_size = 270;
    let frame_start = 721;
    let window_size = (sample_rate * 10) as usize;
    let total_duration = samples.len() as f64 / sample_rate as f64;
    let padded_length = if samples.len() % window_size != 0 {
        samples.len() + (window_size - (samples.len() % window_size))
    } else {
        samples.len()
    };
    let total_windows = (padded_length + window_size - 1) / window_size;
    println!("Audio stats:");
    println!("  Total samples: {}", samples.len());
    println!("  Sample rate: {} Hz", sample_rate);
    println!("  Duration: {:.2} seconds", total_duration);
    println!(
        "  Window size: {} samples ({} seconds)",
        window_size,
        window_size as f64 / sample_rate as f64
    );
    println!("  Total windows needed: {}", total_windows);
    let padded_samples = {
        let mut padded = Vec::from(samples);
        let padding_needed = padded_length - samples.len();
        println!("  Adding {} padding samples", padding_needed);
        padded.extend(vec![0; padding_needed]);
        padded
    };
    //An error occurs when we try to process a very small speech segment (only 270 samples in this case) in knf_rs::compute_fbank
    //Processing segment: 448.80s - 448.81s (duration: 0.01s, samples: 270)
    //thread 'main' panicked at examples/infinite.rs:25:10:
    //called Result::unwrap() on an Err value: The frames array is empty. No features to compute.
    //Location:
    // crates/knf-rs/src/lib.rs:38:9
    //note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
    let min_segment_samples = (sample_rate as f64 * 0.1) as usize;

    let mut window_count = 0;
    let mut is_speeching = false;
    let mut offset = frame_start;
    let mut start_offset = 0.0;
    let mut current_position = 0;
    let mut window_segments: Vec<Segment> = Vec::new();
    Ok(std::iter::from_fn(move || {
        loop {
            // Return any pending segments first
            if !window_segments.is_empty() {
                return Some(Ok(window_segments.remove(0)));
            }
            // Check if we've processed all samples
            if current_position >= padded_samples.len() {
                // Handle any final speech segment
                if is_speeching {
                    let start = start_offset / sample_rate as f64;
                    let end = offset as f64 / sample_rate as f64;
                    let start_idx = (start * sample_rate as f64) as usize;
                    let end_idx = (end * sample_rate as f64) as usize;

                    // Check if segment is long enough
                    if (end_idx - start_idx) >= min_segment_samples {
                        window_segments.push(Segment {
                            start,
                            end,
                            samples: samples
                                [start_idx.min(samples.len() - 1)..end_idx.min(samples.len())]
                                .to_vec(),
                        });
                    } else {
                        println!(
                            "  Skipping too short segment: {}s to {}s (duration: {:.3}s)",
                            start,
                            end,
                            end - start
                        );
                    }
                    is_speeching = false;
                }
                return None;
            }
            // Process next window
            let window_end = (current_position + window_size).min(padded_samples.len());
            let window = &padded_samples[current_position..window_end];
            window_count += 1;
            println!(
                "Processing window {}/{} ({:.2}s to {:.2}s)",
                window_count,
                total_windows,
                current_position as f64 / sample_rate as f64,
                window_end as f64 / sample_rate as f64
            );
            // Convert and process window
            let array = ndarray::Array1::from_iter(window.iter().map(|&x| x as f32));
            let array = array.view().insert_axis(Axis(0)).insert_axis(Axis(1));

            let inputs = match ort::inputs![array.into_dyn()] {
                Ok(inputs) => inputs,
                Err(e) => return Some(Err(eyre::eyre!("Failed to prepare inputs: {:?}", e))),
            };

            let ort_outs = match session.run(inputs) {
                Ok(outputs) => outputs,
                Err(e) => return Some(Err(eyre::eyre!("Failed to run the session: {:?}", e))),
            };

            let ort_out = match ort_outs.get("output").context("Output tensor not found") {
                Ok(output) => output,
                Err(e) => return Some(Err(eyre::eyre!("Output tensor error: {:?}", e))),
            };

            let ort_out = match ort_out.try_extract_tensor::<f32>() {
                Ok(tensor) => tensor,
                Err(e) => return Some(Err(eyre::eyre!("Tensor extraction error: {:?}", e))),
            };
            println!("  Processing tensor of shape: {:?}", ort_out.shape());
            // Process segments in window
            for row in ort_out.outer_iter() {
                for sub_row in row.axis_iter(Axis(0)) {
                    let max_index = match find_max_index(sub_row) {
                        Ok(index) => index,
                        Err(e) => return Some(Err(e)),
                    };

                    if max_index != 0 {
                        if !is_speeching {
                            start_offset = offset as f64;
                            is_speeching = true;
                            println!(
                                "  Speech started at {:.2}s",
                                start_offset / sample_rate as f64
                            );
                        }
                    } else if is_speeching {
                        println!(
                            "  Speech ended at {:.2}s",
                            offset as f64 / sample_rate as f64
                        );
                        let start = start_offset / sample_rate as f64;
                        let end = offset as f64 / sample_rate as f64;
                        let start_idx = (start * sample_rate as f64) as usize;
                        let end_idx = (end * sample_rate as f64) as usize;

                        window_segments.push(Segment {
                            start,
                            end,
                            samples: samples
                                [start_idx.min(samples.len() - 1)..end_idx.min(samples.len())]
                                .to_vec(),
                        });
                        is_speeching = false;
                    }
                    offset += frame_size;
                }
            }
            // Move to next window
            current_position = window_end;

            // If we found segments in this window, return the first one
            if !window_segments.is_empty() {
                return Some(Ok(window_segments.remove(0)));
            }
        }
    }))
}

tried to hack this ( must meet the minimum length requirement of 0.1 seconds before being added to window_segments!!)
} else if is_speeching {
    println!(
        "  Speech ended at {:.2}s",
        offset as f64 / sample_rate as f64
    );
    let start = start_offset / sample_rate as f64;
    let end = offset as f64 / sample_rate as f64;
    let start_idx = (start * sample_rate as f64) as usize;
    let end_idx = (end * sample_rate as f64) as usize;

    // Add minimum segment length check here too
    if (end_idx - start_idx) >= min_segment_samples {
        window_segments.push(Segment {
            start,
            end,
            samples: samples
                [start_idx.min(samples.len() - 1)..end_idx.min(samples.len())]
                .to_vec(),
        });
    } else {
        println!(
            "  Skipping too short segment: {}s to {}s (duration: {:.3}s)",
            start,
            end,
            end - start
        );
    }
    is_speeching = false;
}

So this currently works with audio files that I tried to test. 😊
pub fn get_segments<P: AsRef<Path>>(
    samples: &[i16],
    sample_rate: u32,
    model_path: P,
) -> Result<impl Iterator<Item = Result<Segment>> + '_> {
    let session = session::create_session(model_path.as_ref())?;
    let frame_size = 270;
    let frame_start = 721;
    let window_size = (sample_rate * 10) as usize;
    let total_duration = samples.len() as f64 / sample_rate as f64;
    let padded_length = if samples.len() % window_size != 0 {
        samples.len() + (window_size - (samples.len() % window_size))
    } else {
        samples.len()
    };
    let total_windows = (padded_length + window_size - 1) / window_size;
    println!("Audio stats:");
    println!("  Total samples: {}", samples.len());
    println!("  Sample rate: {} Hz", sample_rate);
    println!("  Duration: {:.2} seconds", total_duration);
    println!(
        "  Window size: {} samples ({} seconds)",
        window_size,
        window_size as f64 / sample_rate as f64
    );
    println!("  Total windows needed: {}", total_windows);
    let padded_samples = {
        let mut padded = Vec::from(samples);
        let padding_needed = padded_length - samples.len();
        println!("  Adding {} padding samples", padding_needed);
        padded.extend(vec![0; padding_needed]);
        padded
    };
    //An error occurs when we try to process a very small speech segment (only 270 samples in this case) in knf_rs::compute_fbank
    //Processing segment: 448.80s - 448.81s (duration: 0.01s, samples: 270)
    //thread 'main' panicked at examples/infinite.rs:25:10:
    //called Result::unwrap() on an Err value: The frames array is empty. No features to compute.
    //Location:
    // crates/knf-rs/src/lib.rs:38:9
    //note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
    //So its fixed!
    let min_segment_samples = (sample_rate as f64 * 0.1) as usize;

    let mut window_count = 0;
    let mut is_speeching = false;
    let mut offset = frame_start;
    let mut start_offset = 0.0;
    let mut current_position = 0;
    let mut window_segments: Vec<Segment> = Vec::new();
    Ok(std::iter::from_fn(move || {
        loop {
            // Return any pending segments first
            if !window_segments.is_empty() {
                return Some(Ok(window_segments.remove(0)));
            }
            // Check if we've processed all samples
            if current_position >= padded_samples.len() {
                // Handle any final speech segment
                if is_speeching {
                    let start = start_offset / sample_rate as f64;
                    let end = offset as f64 / sample_rate as f64;
                    let start_idx = (start * sample_rate as f64) as usize;
                    let end_idx = (end * sample_rate as f64) as usize;

                    // Check if segment is long enough
                    if (end_idx - start_idx) >= min_segment_samples {
                        window_segments.push(Segment {
                            start,
                            end,
                            samples: samples
                                [start_idx.min(samples.len() - 1)..end_idx.min(samples.len())]
                                .to_vec(),
                        });
                    } else {
                        println!(
                            "  Skipping too short segment: {}s to {}s (duration: {:.3}s)",
                            start,
                            end,
                            end - start
                        );
                    }
                    is_speeching = false;
                }
                return None;
            }
            // Process next window
            let window_end = (current_position + window_size).min(padded_samples.len());
            let window = &padded_samples[current_position..window_end];
            window_count += 1;
            println!(
                "Processing window {}/{} ({:.2}s to {:.2}s)",
                window_count,
                total_windows,
                current_position as f64 / sample_rate as f64,
                window_end as f64 / sample_rate as f64
            );
            // Convert and process window
            let array = ndarray::Array1::from_iter(window.iter().map(|&x| x as f32));
            let array = array.view().insert_axis(Axis(0)).insert_axis(Axis(1));

            let inputs = match ort::inputs![array.into_dyn()] {
                Ok(inputs) => inputs,
                Err(e) => return Some(Err(eyre::eyre!("Failed to prepare inputs: {:?}", e))),
            };

            let ort_outs = match session.run(inputs) {
                Ok(outputs) => outputs,
                Err(e) => return Some(Err(eyre::eyre!("Failed to run the session: {:?}", e))),
            };

            let ort_out = match ort_outs.get("output").context("Output tensor not found") {
                Ok(output) => output,
                Err(e) => return Some(Err(eyre::eyre!("Output tensor error: {:?}", e))),
            };

            let ort_out = match ort_out.try_extract_tensor::<f32>() {
                Ok(tensor) => tensor,
                Err(e) => return Some(Err(eyre::eyre!("Tensor extraction error: {:?}", e))),
            };
            println!("  Processing tensor of shape: {:?}", ort_out.shape());
            // Process segments in window
            for row in ort_out.outer_iter() {
                for sub_row in row.axis_iter(Axis(0)) {
                    let max_index = match find_max_index(sub_row) {
                        Ok(index) => index,
                        Err(e) => return Some(Err(e)),
                    };

                    if max_index != 0 {
                        if !is_speeching {
                            start_offset = offset as f64;
                            is_speeching = true;
                            println!(
                                "  Speech started at {:.2}s",
                                start_offset / sample_rate as f64
                            );
                        }
                    } else if is_speeching {
                        println!(
                            "  Speech ended at {:.2}s",
                            offset as f64 / sample_rate as f64
                        );
                        let start = start_offset / sample_rate as f64;
                        let end = offset as f64 / sample_rate as f64;
                        let start_idx = (start * sample_rate as f64) as usize;
                        let end_idx = (end * sample_rate as f64) as usize;

                        // Add minimum segment length check here too
                        if (end_idx - start_idx) >= min_segment_samples {
                            window_segments.push(Segment {
                                start,
                                end,
                                samples: samples
                                    [start_idx.min(samples.len() - 1)..end_idx.min(samples.len())]
                                    .to_vec(),
                            });
                        } else {
                            println!(
                                "  Skipping too short segment: {}s to {}s (duration: {:.3}s)",
                                start,
                                end,
                                end - start
                            );
                        }
                        is_speeching = false;
                    }
                    offset += frame_size;
                }
            }
            // Move to next window
            current_position = window_end;

            // If we found segments in this window, return the first one
            if !window_segments.is_empty() {
                return Some(Ok(window_segments.remove(0)));
            }
        }
    }))
}

So this currently works with audio files that I tried to test. 😊

Looks like you found the issue. I forgot to collect the whole segments and instead got only one from the for loops.
You can use VecDeque which is more efficient when needing kind of queue structure.
The only issue with that, is that it doesn't yield each segment immediately (you push them first)
I want to yield each one as soon as possible but it's not simple with Rust's generators/iterators. https://users.rust-lang.org/t/how-to-create-iterator-with-results/121834/3

yes, its very poorly written and slow actually 🙂. I haven't analyzed this in detail yet, I've been dealing with this for a long time and I started to get a little confused 😂 . I just wanted to share it as soon as I figured it out 😊

note that, since the issue fixed with the v0.3.0-beta.0, feel free to close this. But my eye is also on here https://users.rust-lang.org/t/how-to-create-iterator-with-results/121834/3 to if we find a better way :-)
Thank you again, really nice work!


Fixed bug in firefox

Fixed string.match bug in firefox
Resolving #50

@FelisPhasma Reviewing this in detail the next time I have five minutes, today or tomorrow, should be merged very soon.

Sorry that took so long, thanks for the PR!


Implementing tests and documentation

@clifinger I think we can write integration test. And We can use mock http request etc.

@shirshak55 yes I think also, I will make the dev branch when I finish my job. but you can start and do a PR :) thank you by the way !

Ok, done, please do your PR on develop :)

@clifinger sure i will probably start once i reach home.

@shirshak55 do you want me to take care of this ticket?

@clifinger yea please

Hi all, I personally tried to use rust unit testing, but I found that
rust is still in an infant state.
I personally found that jest is way better and flexible and faster to work with
With the combination of supertest that uses superagent, tests are easy to write and easy to maintain.
I also use Clion and it still has issues to run system tests of application that accepting parameters, due to mix of parameters you passing to rust and to application.
Here is a screenshot of unit testing I currently have

I have organized the execution the way that during start jest will compile API and restart it automatically and run it in debug mode with logging enabled, so you can see debug information from rust code as well as debug information from the test itself.
I basically took the best from two worlds.
I think that in most of the cases the web front will be anyway written on javascript (React, Angular, Vue) and for me is OK to use javascript for integration testing.
The question is are you interested in me to submit the patch with jest unit testing?

@olexiyb hey there i agree the problem is code reuse i guess but i still think node js  & jest is perfect for testing such thing as test usually don't end up in hot path .


Fix: DNS return value

/cc @AkinoKaede

Codecov Report

Merging #1242 (64ba389) into master (50bcb68) will decrease coverage by 0.26%.
The diff coverage is 0.00%.

@@            Coverage Diff             @@
##           master    #1242      +/-   ##
==========================================
- Coverage   44.86%   44.60%   -0.27%
==========================================
  Files         485      476       -9
  Lines       29498    29403      -95
==========================================
- Hits        13235    13115     -120
- Misses      14868    14882      +14
- Partials     1395     1406      +11

Impacted Files
Coverage Δ

app/dns/nameserver_doh.go
68.05% <0.00%> (-0.64%)
:arrow_down:

app/dns/nameserver_quic.go
73.02% <0.00%> (-0.69%)
:arrow_down:

app/proxyman/outbound/errors.generated.go
0.00% <0.00%> (-100.00%)
:arrow_down:

transport/internet/udp/dispatcher.go
64.76% <0.00%> (-12.39%)
:arrow_down:

common/task/task.go
88.88% <0.00%> (-7.41%)
:arrow_down:

common/buf/reader.go
82.35% <0.00%> (-5.89%)
:arrow_down:

testing/servers/tcp/tcp.go
81.81% <0.00%> (-5.46%)
:arrow_down:

app/proxyman/outbound/handler.go
38.05% <0.00%> (-4.48%)
:arrow_down:

transport/internet/udp/hub.go
73.61% <0.00%> (-4.17%)
:arrow_down:

proxy/freedom/freedom.go
45.00% <0.00%> (-4.00%)
:arrow_down:

... and 19 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 50bcb68...64ba389. Read the comment docs.

Thanks, it is works on my computer.


Mattermost 3.5

Hi,
Could you update your Docker images to use the new 3.5 release ?
Thx

Created a pull request for it, see https://github.com/mattermost/mattermost-docker/pull/65- @npcode, can you help with review?

Thank you.
I guess the same applies for the 2 others containers (db and web) ?

Please tag the 3.5.1 release for Docker hub to reflect it

@fculpo the docker hub image is updated to 3.5.1. The source repo is mattermost/mattermost-docker-preview.

I am using https://hub.docker.com/r/mattermost/mattermost-prod-app/ and https://hub.docker.com/r/mattermost/mattermost-prod-db/ and they don't have 3.5.1 atgs.

Ah, got it, thanks for pointing this out @fculpo. We are in the process of transitioning maintainership of the repos and then we will make sure the tags are updated for all the docker containers.

@compass
The tags on the docker hub repos are automatically generated, but some of them are still pointing to 3.4.1. Wondering if you'd be able to help take a look?

https://hub.docker.com/r/mattermost/mattermost-prod-web/tags/
https://hub.docker.com/r/mattermost/mattermost-prod-db/tags/
https://hub.docker.com/r/mattermost/mattermost-prod-app/tags/

@fculpo 3.5.1 is tagged. Do you need 3.5.0? I need to figure out which commit is for 3.5.0 otherwise here is the new tag: https://hub.docker.com/r/mattermost/mattermost-prod-app/tags/

3.5.1 is fine for me. Thank you


add Lorenz 96 model (but cannot add DynamicalSystems dependency, so n…

…ot compiled yet)

:warning: Please install the  to ensure uploads and comments are reliably processed by Codecov.
Codecov Report
Attention: Patch coverage is 0% with 19 lines in your changes missing coverage. Please review.

Project coverage is 84.29%. Comparing base (37da88d) to head (281f3d6).
Report is 2 commits behind head on main.

Files with missing lines
Patch %
Lines

src/Lorenz_models.jl
0.00%
19 Missing :warning:

:exclamation: Your organization needs to install the Codecov GitHub app to enable full functionality.

:exclamation:  There is a different number of reports uploaded between BASE (37da88d) and HEAD (281f3d6). Click for more details.
HEAD has 2 uploads less than BASE

Flag
BASE (37da88d)
HEAD (281f3d6)

3
1

Additional details and impacted files
@@             Coverage Diff              @@
##              main       #9       +/-   ##
============================================
- Coverage   100.00%   84.29%   -15.71%
============================================
  Files            3        3
  Lines          103      121       +18
============================================
- Hits           103      102        -1
- Misses           0       19       +19

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.


Explicit move binding mode

This RFC suggests using the move keyword to explicitly specify the moving binding mode to override match ergonomics
Rendered

For context, there’s a URLO discussion where the motivation for writing this RFC probably emerged. I don’t know yet what I’d like to contribute from that thread to this discussion… but to paraphrase my own take on binding modes in the context of match ergonomics from that thread:
I believe it might be worth a change to lint (or eventually even error, or error-by-default-lint) in general against any ref x, ref mut x or mut x that appears in places where match ergonomics have changed the default binding mode. I think the current behavior has confusion points such as

ref x and x, or ref mut x and x, are identical in meaning in match-ergonomics contexts, and different syntax for the same thing can lead to confusion, in particular when their meaning differs significantly in other contexts.
the current state of mut x and x (in the context of match ergonomics) differing in whether or not binding-by-reference happens is just obviously confusing and nothing else

In case that isn’t clear from the above, I believe that complicated settings should require the user to fall back to patterns that properly match the type, i.e. to no longer use match ergonomics. This could also be aided by help messages in diagnostics.

You are correct that this RFC originates from that discussion. I originally included a link to it but was advised against it by a member of the Discord community. I will update the alternatives section to elaborate further on your alternative.

As alternative: Rust use *const and *mut as & and &mut for pointers. So it is handy use const same way here.
let (x, const y, mut z) = &mut xyz;
// The type of `x` is `&mut i32` and
// the type of `z` is `&i32` (and the binding is mutable)
// the type of `z` is `i32` (and the binding is mutable)

let (x, const y) = &xy;
// The type of `x` is `&i32` and
// the type of `y` is `i32`

As an alternative: Rust use *mut and *const for raw pointers. So it is handy to reuse this keyword here
let (x, const y, mut z) = &mut xyz;
// The type of `x` is `&mut i32` and
// the type of `y` is `&i32` and
// the type of `z` is `i32` (and the binding is mutable)

let (x, const y) = &xy;
// The type of `x` is `&i32` and
// the type of `y` is `i32`

P.S. I is already legal to write
let (x, mut y) = &xy;
// The type of `x` is `&i32` and
// the type of `y` is `i32`

For context, an alternative to ref/move

(ref | move)? mut? IDENTIFIER (@ PatternNoTopAlt)?

is mut/const

ref? (const| mut)? IDENTIFIER (@ PatternNoTopAlt)?

There is no need for anything like this. It's just piling even more special cases on top of the already-confusing match "ergonomics". Just make sure that the pattern's type matches that of the value, it's as simple as that.

This isn’t a special case. It’s simply filling an obvious gap in the existing match ergonomics. If you don’t like match ergonomics, that’s fine, but it’s here and people use it.
Even if the “better” approach is to just not use match ergonomics, having a half-baked feature in the language is worse than having one that’s on par with the alternative in what it can do.
Also, have you read the alternatives section of the RFC? It contains an alternative implementation of match ergonomics suggested by @steffahn that may be more to your liking.

I consider the RFC well-motivated: from conversations with people learning Rust, match ergonomics has generally been a success, but it definitely has nasty edge cases around Copy types. We expected at some point to resolve those by making references to copy types (i.e., values of type &impl Copy) usable more like the underlying type itself, but we've made no progress on adding coercions or other rules to make that true, and in the meantime I've become generally more pessimistic about the ability for coercions to fully hide the distinction between &impl Copy and impl Copy.
The choice of move keyword makes sense but is also confusing, in that moving a copy type doesn't move, and actually moving (in the strict sense) from inside a reference is always an error. The fact that taking ownership of a type is calling moving in the closure sugar, and that moving only copies a copy type, is definitely a bit of pre-existing confusion that we woudl be doubling down on here. I'm not sure how to feel about that, tbh.
The other obvious solution would be to allow & patterns in this position -- i.e., let & be used to "cancel out" an implicit ref binding mode. I think @cramertj was going to propose this but it never happened.
I've definitely reached the point where I'd like to see us do something here. I kind of like the move keyword option a bit more than the &x option, in that &x is known to be confusing, but I am a bit worried about the choice of move keyword here.

That's a good point and something I had not considered. I will update the RFC to be more careful with the word “move”. Also note the alternative keywords proposed.
A question: It seems to me (although I am not versed in unsafe Rust) that strictly speaking it would be possible albeit possibly unsound for a type to implement Copy while its constituent types (the ones matched over) do not—or is this always undefined behavior?

I think using the move keyword for it isn't that bad as that's how move closures and move async blocks use it too, so it would only be consistent to use move here as well (though maybe in a future edition they all could use a better keyword).

I really like @steffahn's idea that &(T, U) could be treated like (&T, &U) in patterns. Here's an example where this would be useful:
some_iter
    .enumerate()
    .filter(|(&i, item)| ...)

Currently the pattern must be written as &(i, ref item). Match ergonomics currently don't work here, because i should be an owned usize, but item should be bound by reference. But I think the above could be allowed and would feel both intuitive and consistent.

My core objection is that this proposal doesn't fix match ergonomics or make it more consistent. Instead, it piles on yet another hack, with likely more unintuitive interactions. Worse, it does that by modifying the pattern syntax, so it affects not just match ergonomics, but any place where a pattern can be used: function and closure arguments, let bindings. The proposed addition is useless and undesirable in all those other cases.
Some more specific issues:

The syntax doesn't make sense. The pattern in match &x already binds to a reference.
match &Some(3) {
  Some(move x) => {}
  _ => {}
}

Here x is a reference. The intuitive reading is that we "move a reference", which is absolutely not the intended semantics. This just doubles-down on the current confusing interpretation of mut bindings. Things get even more confusing if the matched field is itself a reference.

The semantics don't make sense. Without match ergonomics, everything is clear: we match a struct/enum by value, all fields are exposed, and you can either move them or create a borrow. With match ergonomics, the matched expression is a reference. The only thing one can naturally produce for its fields is references. How can you even more a field which you don't own? So either the field has type allowing it to be moved out of a borrowed state (i.e. it's Copy), in which case one can do this move manually in a match arm, or it should be a compile error "move of borrowed value" anyway.

For by-value matches, the new binding mode is useless. It's just syntactic noise, and the only reasonable treatment is to lint against it. Still, you can be sure that some people will ignore/disable this lint, and insist on "explicit moves", so the codebases will be littered with useless moves.

The keyword is actually too good to waste on this hack. There are many other potential uses for move, including in patterns, which would be confusing or incompatible with the proposed addition. E.g. there are many discussions about &move T references, which would naturally require ref move binding modes in patterns.

I don’t see this as piling on another hack on top of match ergonomics. While I grant this does not make match ergonomics more intuitive, it does fill a hole in the currently existing implementation of match ergonomics. When introducing something that changes a default, it seems to me that specifying something non-default is obviously a necessary element, which was neglected in the match ergonomics RFC. I agree that the current implementation of match ergonomics is confusing, and I believe this is in part because the idea of binding modes is not well-known and not fleshed out, which this proposal aims to rectify partially.

Yes, mut is a confusing case, but I believe it becomes less confusing when move exists a binding mode specifier with similar properties. The most intuitive mental model that fits your description would be @steffahn’s idea. Not also that move is used consistently with the terminology in the match ergonomics RFC.

No, the semantics make sense. We are not moving a field we don’t own, we are changing the binding mode to the moving mode, which is the default. This causes a copy when the value is Copy, and an error otherwise. This is an argument over nomenclature: Should we say that a copy is strictly not a move, or that a move can be a copy? I believe that saying that a copy is a move that can be used in its original place afterward is a fine mental model. Generally I find this argument is much more an argument against match ergonomics as-is and less an argument against this proposal.

I don’t think so. The same would be possible with existing match ergonomics (explicit ref) but I have not come across this (feel free to educate me). This proposal actually makes this less likely as linting against unnecessary ref and ref mut is part of it.

I don’t see how this keyword is incompatible with that proposed addition. ref move is well-distinct from move. In fact, I believe even a differentiation between ref mut and mut ref would be perfectly understandable, as is suggested in the alternatives section.

I grant that you present strong points against the current implementation of match ergonomics. But a replacement of match ergonomics can happen even after this proposal, and this proposal can serve a purpose in providing more flexible match ergonomics in the mean-time.

I don’t see this as piling on another hack on top of match ergonomics. While I grant this does not make match ergonomics more intuitive, it does fill a hole in the currently existing implementation of match ergonomics.

The whole (supposed) point of match ergonomics was/is to make patterns more intuitive. If any addition fails this criterion, then it's pointless.
Since moving and referencing can already be accomplished by being explicit about the pattern, there's no need for a completely redundant way to do the same thing with a different syntax. It simply doesn't carry its weight, and since you need to be explicit anyway, it doesn't make anything easier at all.

Using ref is less readable, more noisy, and tedious to write

If ref is unreadable, noisy, and tedious to write, then why isn't the same true for move (which is longer)? This argument is inconsistent.

We are not moving a field we don’t own, we are changing the binding mode to the moving mode, which is the default.

This phrase only makes sense if you know exactly the algorithm of match ergonomics. The point of match ergonomics is exactly that the user does not need to know or care about "binding modes".  Once you get into "binding modes" you'd be better served by writing out the classic derefed match with ref and ref mut explicitly.
If you don't know about "binding modes", the proposed syntax makes zero sense.

This is an argument over nomenclature: Should we say that a copy is strictly not a move, or that a move can be a copy?

That's pedantic. Nobody cares about that, beyond the first steps in Rust when they learn that every move is a copy, but the compiler may prevent you from using the original.

The same would be possible with existing match ergonomics (explicit ref) but I have not come across this (feel free to educate me).

I have seen plenty of such code in the wild. Most often it's a codebase which was started before match ergonomics were implemented. Sometimes it's a preference of the people writing it. In those cases match ergonomics aren't used, and the matching is done old-style, with a dereference on the scrutinee and explicit ref/ref mut bindings.
I have seen people argue that old-style matching makes it more explicit which of the bindings are moved, and which are borrowed. With inferred types of scrutinees, I tend to agree, though I still prefer match ergonomics, both because it's shorter and because I find the binding modes very counterintuitive.

That said, I like @steffahn 's suggestion (the alternative you listed). I have often wondered why match ergonomics doesn't already work this way. Is there a reason beyond "nobody implemented it"?

That said, I like @steffahn 's suggestion (the alternative you listed). I have often wondered why match ergonomics doesn't already work this way. Is there a reason beyond "nobody implemented it"?

I have talked to other community members on the community Discord Server about this and there seems to be no clear answer. Perhaps no-one came up with this during the match ergonomics RFC period. However there may be subtle problems in the implementation which is why I didn’t feel confident to suggest this change. I feel this proposal is much more conservative as it suggest exposing functionality that is already present (mut’s effect on match ergonomics) and does not require an edition boundary.

I have seen plenty of such code in the wild. Most often it's a codebase which was started before match ergonomics were implemented. Sometimes it's a preference of the people writing it. In those cases match ergonomics aren't used, and the matching is done old-style, with a dereference on the scrutinee and explicit ref/ref mut bindings.

I was talking about unnecessary ref or ref mut, when match ergonomics already set them as the default. Have you seen that?

Well, the point of match ergonomics is to avoid writing ref/ref mut. So no, I haven't seen those used together.
Please don't spread your replies over many messages, it makes hard to keep track of discussion.

I was replying to separate messages so I kept my replies in separate messages. Why would I pack together replies that don’t belong together?

I kind of like the move keyword option a bit more than the &x option, in that &x is known to be confusing, but I am a bit worried about the choice of move keyword here.

Regardless of choice of keyword (let's go with move for the sake of the argument), if people learn that move x can be used in certain contexts to turn what used to be a reference x: &i32, without the word move, into an owned x: i32, there will IMO inevitably be confusion as to why that doesn't work consistently everywhere. It will intuitively function like a dereferencing pattern, because the thing that it intuitively does is dereferencing - the fact that the "true" functionality would be to affect the "default binding mode" is a language design detail that most people will be unaware of, or at least not know in full detail.
Of course, assuming this outcome is realistic, it would be a bad outcome, because we already have true dereferencing patterns &x and &mut x, so if the common perception would be that move x is effectively a third kind of dereferencing pattern that must be used in certain cases, whereas it cannot be used in others, that seems to me like bad language design and unnecessary complication. E. g. iterating over HashMap<i32, String>, it you want k: i32 and v: &String, you would need to write .iter().for_each(|(&k, v)|) but for Vec<(i32, String)> it would be .iter().for_each(|(move k, v)|) – a differentiation in contrast to the case of a simple (k, v) pattern, which can be used for both consistently and with the consistent outcome k: &i32 and v: &String.
If we follow argument that &x is more confusing than something like move x, which may very well be true, as reference patterns are known to be a slightly hard thing to learn due to the dual nature of patterns, then someone might even come to prefer move x and/or learn about it first, and then wonder why they cannot simply write .iter().for_each(|(move k, v)|) in the HashMap<i32, String> case - or possibly even - why they can still write it, but with vastly different outcome (as move k would change nothing compared to k).

I feel this proposal is much more conservative as it suggest exposing functionality that is already present (mut’s effect on match ergonomics) and does not require an edition boundary.

Regarding edition boundaries... the kind of syntax that might change in meaning over an edition is mut x and ref x/ref mut x in by-reference default binding mode contexts. These are of limited usefulness anyways, their new respective meanings would be to create a reference held in a mutable variable, and to create a reference to a reference. Both are operations that used to be completely impossible to achieve anyways with normal patterns and binding modes before any match ergonomics, so they cannot be all that important.
Without/before an edition boundary, we can simply lint against all this syntax that would change in meaning (because it would then become a corner case incompatible with the new concept of how match ergonomics operate, only kept for backwards compatibility). Even after an edition we could still consider just having it error instead of introducing the new consistent meaning of mut x/ref x/ref mut x in these contexts. If there's not much of a practical need to ever bind to references in mutable variables or references-to-references, that would not be much of a restriction.

@steffahn
That's why const (not mut) is an alternative to move/ value(not ref). It is already in use for raw types, and the content of immutability is clear

@VitWW
I don’t think const is a good keyword, since it usually implies knowledge about the value at compile time. Raw pointers are the exception to this, not the rule. Also, it highlights that the value is immutable, as opposed to mut, but mut’s behaviour here is already confusing, and we’d rather highlight that mut and move don’t bind by reference but by value.

May I leave my two cents?
I think Rust should go in the opposite direction. Rely solely on match ergonomics and deprecate the ref keyword.
In my experience, I manage to never use the ref keyword (almost nobody in our team/project uses it). Almost all code can be written without ref in match, and exceptions are so rare that the language simplification outweighs these rare inconveniences.

Rely solely on match ergonomics and deprecate the ref keyword.

That would be massively harmful, primarily in unsafe code. Only having an option where types do not match is unacceptable in any language seeking correctness to any degree.

@H2CO3 Can you elaborate on that further? With this RFC match ergonomics are almost identical in power to "Rust 2015 matching", meaning that Rust 2015 matching can almost be deprecated. I don't know how any of this has anything to do with unsafe or types that don't match.

With this RFC match ergonomics are almost identical in power to "Rust 2015 matching"

First, I don't care about "power"; it's not what I am talking about. I am talking about situations where whether or not a type is a reference is important, and you want to be explicit about types rather than letting the compiler second-guess you. In unsafe, this can cause problems (read: even UB). Here's a trivial demonstration where the call is intended to overwrite x = 137 with the value 42 but fails to, due to match ergonomics. The equivalent with explicit patterns works as intended. This is "only" a logic bug, but if the value of x were relied on by unsafe code, it can trivially lead to UB. E.g. you can rewrite the above example with 0 and a non-zero value instead, which then gets fed into NonZeroU8::new_unchecked(). Here it is.

meaning that Rust 2015 matching can almost be deprecated

There's no need to deprecate anything. Just because there's a convenience feature, it doesn't mean that the option of being explicit should be taken away from people. This is exactly the kind of slippery slope I and many others had been worrying and warning about when match ergonomics was introduced.

@H2CO3 you example show how match ergonomics might be dangerous in unsafe context. OK.
How ref would make code safe? You didn't use ref in your examples.

There's no need to deprecate anything.

I explained the reasons: ref is needed rarely, code can be written without it, and we do not need to have two ways to write the same code. Maybe these are not compelling reasons, I don't know.
If you are arguing that match ergonomics need to be deprecated instead, this is a different topic.

If you are arguing that match ergonomics need to be deprecated instead

I was not; refrain from putting words into my mouth.

How ref would make code safe? You didn't use ref in your examples.

Being explicit about the types would make the code safe. That may or may not involve ref.

@H2CO3

I was not; refrain from putting words into my mouth.

I'm sorry Árpád, I didn't mean to. Just trying to understand.

Being explicit about the types would make the code safe. That may or may not involve ref

I generally agree about type safety: that's what we love Rust for. I didn't get how ref makes code safer?

@H2CO3
I believe I now understand what your concern is. In your example, the programmer confuses the &mut (usize, usize) with a (usize, usize), but this isn’t an error because match ergonomics kick in. Am I understanding that correctly?

I think your example also shows how as together with _ can be dangerous due to it allowing both usize and &mut usize to be coerced to pointers in different ways. If a method was used for each you would’ve gotten an error due to the wrong type. However, I think that if you wanted to be “explicit with types” you could’ve just written as *mut () explicitly and you would’ve gotten an error.

@stepancheg I wouldn't have fought painfully for years (and I mean literally years) to get a clippy lint accepted to enforce explicit binding modes if it were useless. I wouldn't have put myself through all of that pain, the attacks, and the insults if I wouldn't get a value out of it,.
So I would appreciate it if everyone started with the assumption that if they don't see a use for something, that doesn't mean nobody else does. And that you don't have to be convinced of it's usefulness for it to be of great value to others.
It has explicit, mechanical functions that no other parts of the language provide:

It allows to reduce the adaptiveness of code to changes, as @H2CO3 demonstrated. If I write a bit of unsafe code, I want to be very explicit and the compiler to tell me to make a decision when something in a used API changes in certain ways. Having the whole language be optimized to "adapt to the situation" is great, except when that change hides a semantic change. Ownership differences are semantic. &T, vs &mut T vs T behave differently, resolve differently, have different types. Lumping them all together syntactically works in the general case, but you still have to account for the one that isn't general.
It allows separating shared and mutable reference bindings in a single pattern. That means match arms don't need extra blocks to get rid of mutability. You know from the pattern signature what will be mutated and what won't. You can't mutate the wrong thing accidentally. Properties like that are why I like Rust. And remember, this is also available in macros where there might not be another chance to change the bindings. Having the correctness enforcing mechanics directly in the pattern syntax enables it in more places.
With the proposed removal, something working for owned local bindings let (x, mut y) suddenly is no longer available for references to other things? Even though shared/exclusive borrowing is one of the most fundamental parts of Rust, so is pattern matching.

So after years of discussions, roadblocks, fighting about this and all other things. I'm sorry I'm not convinced we need to remove it because not everyone uses it. There are still no suitable replacements for the things it does.
If people want to "fix" match ergonomics, I'd propose not going for just 90% of cases and have the rest not work, and not going for a hard-to-one-side total removal that leaves parts of the community in the dust. Instead go for a holistic approach where the explicit underlying mechanics give explicit control, and have a high level approach for those that don't care and where it doesn't matter much.

@phaylon I should choose my words more carefully.
I'll rephrase. I read code by various people, including open source project, and I see that ref keyword is used not very often, and and in most of these places code can be easily rewritten with match ergonomics without hurting code quality.
Even if some people find ref useful, I argue, that the language is better it there's fewer ways to write the same code (if it does not make code more verbose).
Basically, simple language is better if it is equally expressible.

It allows to reduce the adaptiveness of code to changes, as @H2CO3 demonstrated

Did he? In his examples, ref keyword was not used.

With the proposed removal, something working for owned local bindings let (x, mut y) suddenly is no longer available for references to other things?

I didn't get that. I'm only talking about ref, not mut. Maybe you could provide specific example where ref is critical?

With the proposed removal, something working for owned local bindings let (x, mut y) suddenly is no longer available for references to other things?

@phaylon Just for clarity: this RFC do not propose anything to remove.
It propose add new kind of bindings for "not ref" - move/value , for example let (value x, value mut y) =  v

Did he? In his examples, ref keyword was not used.

You keep coming back to whether ref was used or not. But it doesn't matter, it's not the point. The point is that explicitness with the type helps.
If you want, you can trivially rewrite my earlier example to include ref by pretending that you want the 2nd element of the tuple to be a reference, and now you have to use ref in the second version. Here is the match ergonomics version, and here. But this is a red herring, it doesn't change either the problem or the solution in any meaningful way.

@phaylon

It allows separating shared and mutable reference bindings in a single pattern. That means match arms don't need extra blocks to get rid of mutability.

You can do this using match ergonomics, as they currently exist, too—you just have to explicitly specify ref if the default binding mode is ref mut. In the spirit of this adaptability, my proposal is to allow switching to a move/copy, too.

@stepancheg

Even if some people find ref useful, I argue, that the language is better it there's fewer ways to write the same code (if it does not make code more verbose).
Basically, simple language is better if it is equally expressible.

But it isn't equally expressible. It can't express the restrictions and it can't express multi-mode destructuring.
The restrictions are of the same value as all other restrictions in Rust. See:
object.method();
// vs
Object::method(&object);

If someone removes Object::method the first one will look for another one in the dereference hierarchy for the object. The second one will fail to compile and alert the developer.
The same applies to match ergonomics vs. explicit binding modes. (a, b) matches (&Type, &Type),  but also &(Type, Type). If I have explicit patterns like &(ref a, ref b) it will fail to compile when the types change.
The multi-mode destructuring capabilities come in when you do things like
let Self {
    ref mut cache,
    ref mut storage,
    ref ids,
} = *self;

where you get exhaustiveness checking, explicit mode checking, and IDE highlighting of mutable bindings at the top of a function giving you detailed context about the things the function manipulates. This is very handy when your type dispatches to some free functions that manipulate the individual components. And that can happen in all more complex scenarios, like state machines:
match st {
    // lots of cases before
    SomeState { id, ref events, ref mut logger } if logger.traced(id) => ...
    SomeState { id, ref mut events, ... } => ...
    // lots of cases after
}

is a lot more expressive and clean to me than
match &mut st {
    // lots of cases before
    SomeState { id, events, logger } if logger.traced(*id) => ...
    SomeState { id, events, ... } => ...
    // lots of cases after
}

The former gives a lot more context to what's going on, applies restrictions (why even give the ability to the code block to mess with the bound id value?)) and the mutated parts are highlighted in the IDE.
And with all language-level restrictions, since they are at the language level instead of just convention, you can count on them to kick in in unsafe code.
@VitWW

@phaylon Just for clarity: this RFC do not propose anything to remove.
It propose add new kind of binding for "not ref" - move/value , for example let (value x, value mut y) =  v

I am aware, apologies for not mentioning it. As you can tell I'm all for more explicitness and control :) It was more intended as a defense of the general idea of control in general, instead of a rebuke of the advancement.

@H2CO3

You keep coming back to whether ref was used or not. But it doesn't matter, it's not the point. The point is that explicitness with the type helps.

Well, you have replied to my comment about proposal to remove ref:

Rely solely on match ergonomics and deprecate the ref keyword.

You said, quoting:

That would be massively harmful, primarily in unsafe code

So I'm asking for explanation/illustration, how exactly removal of ref would be massively harmful in unsafe code.

But this is a red herring, it doesn't change either the problem or the solution in any meaningful way.

Equally incorrect code can be easily written with ref: example.

Anyway, now that I've given my defense of explicit binding modes, I'll go back to lurking. I hope it will help demonstrate the value it has to some of us, and how expanding the ways to fully qualify patterns as the proposal attempts are things worthy of consideration.
And again: Apologies to OP for it being more expansive than I had anticipated.

While Proposal #3627 (Match ergonomics 2024) is accepted, is this proposal is still valid?
Is it need to update?


[NSE-610] hashagg opt#2

What changes were proposed in this pull request?
clean up code path for hashagg with multiple keys

the big loop should be as tight as possbile
remove the redundant lookup logic in hashmap

Signed-off-by: Yuan Zhou<EMAIL_ADDRESS>How was this patch tested?
pass jenkins

verified locally, merge first


doc: improve capability doc by providing a better explanation over the  deep insight level

Description

doc: improve capability doc by providing a better explanation over the  deep insight level
Add k8s api convention links/info to let the authors follow the good practices
Add the links for the metrics documentation and for let them be aware of the helpers provided to them

@sradco

/lgtm


[HOLD on E/E #347391] Scan - Detach receipt message mentions (none) as merchant for scan request with merchant

If you haven’t already, check out our contributing guidelines for onboarding and email<EMAIL_ADDRESS>to request to join our Slack channel!

Version Number: 1.4.54-1
Reproducible in staging?: Y
Reproducible in production?: N
If this was caught during regression testing, add the test name, ID and link from TestRail: N/A
Issue reported by: Applause - Internal Team
Action Performed:

Go to staging.new.expensify.com
Go to workspace chat
Create a scan request
Go to request details page
Manually enter amount and merchant
Click on the receipt > 3-dot menu > Delete receipt
Delete the receipt
Return to expense report

Expected Result:
The detach receipt message should mention the correct merchant that is entered in Step 5
Actual Result:
The detach receipt message mentions (none) as merchant instead of the entered merchant
Workaround:
Unknown
Platforms:

Which of our officially supported platforms is this issue occurring on?

[x] Android: Native
[x] Android: mWeb Chrome
[x] iOS: Native
[x] iOS: mWeb Safari
[x] MacOS: Chrome / Safari
[x] MacOS: Desktop

Screenshots/Videos
Add any screenshot/video evidence

https://github.com/Expensify/App/assets/78819774/47c164f0-81d2-4903-81fe-49d9e79c4c0b
View all open jobs on GitHub

@NikkiWines  FYI I haven't added the External label as I wasn't 100% sure about this issue. Please take a look and add the label if you agree it's a bug and can be handled by external contributors

We think that this bug might be related to #wave-collect - Release 1

Definitely comes from that PR, but I don't think this is technically a blocker. Pretty sure it's a byproduct of surfacing these Expensify Classic report actions on New Expensify. I see the same behavior if I repeat the test on Expensify Classic.
cc: @Beamanator (since you were involved in that linked PR) looks like we might have a bug in some of the Web report action code that's not retaining the merchant here

I agree this isn't a blocker, especially if it works the same on oldDot. Something for us to fix when we move these messages to native newDot actions. cc @dylanexpensify.

nice, agree!

Cool, sounds like we don't have anything actionable here for a bit. Going to put this on hold and unassign myself

same!

same

Same

No update!

Off hold now, cc @NikkiWines !

Let's get this retested to confirm the bug is still occurring since it's been a while 🙇

FAIR! :D
On Mon, Aug 5, 2024 at 1:51 PM Nikki Wines @.***> wrote:

Let's get this retested to confirm the bug is still occurring since it's
been a while 🙇
—
Reply to this email directly, view it on GitHub
https://github.com/Expensify/App/issues/38541#issuecomment-2269001774,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AOKVCABSPRROONXDIKROA6TZP5YNFAVCNFSM6AAAAABE4O6HXCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENRZGAYDCNZXGQ
.
You are receiving this because you were assigned.Message ID:
@.***>

Could not repro


Allow control of the doughnut chart radius

Adds a new option, radiusPercentage that shrinks the outside radius of doughnut / pie charts. A percentage is used to enable more flexibility during responsive conditions.
Closes: #3923

Maybe this should be called padding to be more generic and be made available to all chart types?

I'm not sure I get the use case. layout.padding could be used, but I don't think that supports percentages.
If planning on having mutiple pies in one canvas, we should debate if having a chartArea per dataset and handling that in layout would be better?

I don't think multiple pies per canvas is something I'd want to do. It seems like it'd be a lot more complex for a few small use cases.
I could make this into a padding option. It'd be inside the chart area only. From the original issue, it was unclear if users wanted pixels or percentages. I went with a percentage to match the cutoutPercentage that already exists for pie/doughnut charts

I think if we made this a padding option it'd be fine to support percentages. But ideally we'd support percentages and pixels

This looks fine to me other than maybe the option name. What did you guys think about it?

I too dislike having 'percentage' in the option name. Both options should be changed to be consistent through. One option would be to use only cutout and radius, requiring string with % for percentage and assume number are pixels. But I think that is out of the scope of this PR.

Yeah, keeping "percentage" out of the name is a good point too. My main thought was to call it padding so that the same name could at some point be used for other chart types

This looks fine to me other than maybe the option name. What did you guys think about it?

The name is consistent with other options currently, so if we want to change those then its can be done in another PR. This should be merged, IMO.

I don't have strong feeling about it. If you'd like to merge that's okay with me. It will need to be rebased though

Going to close this. I'm sure there's a better way to achieve this


vendor latest github.com/urfave/cli

Change from an external patched branch to the upstream master. The
vendored code is indentical to the previous one.
Signed-off-by: Valentin Rothberg<EMAIL_ADDRESS>

Notice that this PR is just changing the remote reference. The vendored code is identical and thus doesn't change.

bot, retest this please

LGTM
and awesome news that your patch made it in upstream.  Thanks again!

LGTM
@rh-atomic-bot r+


Spider: St. Louis Development Corporation Board

URL: https://www.stlouis-mo.gov/government/departments/sldc/boards/St-Louis-Development-Corporation-Board.cfm
Spider Name: stl_development_corp
Agency Name:  St. Louis Development Corporation Board
See the contribution guide for information on how to get started

I'm going to start working on this spider.


Messy GUI

Hi, seems buttons and inscriptions moving with window borders may make messy view sometimes.

Well, that has an easy fix: don't open the extension in landscape mode and with the console also open.
PRs with UI fixes are welcome!


Cannot launch with another rpc client

Hi, I'm having trouble launching the server when I have another plugin flatten.nvim which connects to the nvim rpc server. Is there a solution to ensure both plugins work at the same time?
E5108: Error executing lua Vim:Error invoking 'nvim_exec_lua' on channel 3:
ch 3 was closed by the client
stack traceback:
        [C]: in function 'rpcrequest'
        ...re/nvim/lazy/one-small-step-for-vimkind/lua/osv/init.lua:134: in function 'launch'
        [string ":lua"]:1: in main chunk

To give a small overview of what's happening, one-small-step-for-vimkind (osv) is spawing a embedded instance of neovim to exchange DAP messages, this is required as part of its good operation. The problem is that flatten.nvim seem to exit that instance immediatly. I haven't tested the code so it's just suppositions but I think if an embedded neovim is spawned within neovim without any argument file, flatten.vnim kills it basically. If I'm correct, any plugin using an embedded neovim instance will be unusable with flatten.nvim. Maybe ask them about this. Even if osv spawns an instance with a dummy file, it will be killed. I don't have a good solution right now, I suggest talking to flatten.nvim's creator for solutions.

Great, I'll make that ugly hack disappear once there is a better solution for it.


Schema Server small fixes

Fixes #1206

Added extra JDBC drivers (mysql, postgresql, sqlserver, hsqldb)
Included boot plugin to create runnable jar for the server
Added ddl update to true for the default application.yml

Vinicius, after thinking some more about it, I don't believe this is something we want to support at the moment unless there is a push from the community with a tangible argument. My biggest concern is  potential dependency conflicts that may be transitively pulled by each driver.
What I would consider is adding something in the docs or project WIKI ,so in case questions arise on how to bring additional drivers as well as which drivers we support we can point users to such doc.


Abstract EventTitle, Name, and Purpose

The three fields EventTitle, Purpose and Name of the Event and Person class respectively, behave quite similarly and thus need to be abstracted out under one class which they can implement from.

Not intending to abstract these 3 classes in the interest of time.


Add: isAuthenticated for session

What's the purpose of this pull request?
Possibility of adding validations in front-end components that depend on the user being logged in to generate different behaviors.
How it works?
When the user is logged the system will create the VtexIdclientAutCookie_account and when the client is logged out the VtexIdclientAutCookie_account is removed.
The session cookie have another behaviour so when the client is logged in or logged out the cookie will always exist and the client can be authenticated, identified or anonymous at the session.
Now we get the information of the namespace isAuthenticated from the session and we save this information at the IndexedDB to be available for the Front End if needed.
How to test it?

Create a session:

curl --location 'https://secure.vtexfaststore.com/api/sessions?sc=1' \
--header 'Content-Type: application/json' \
--data '{}
'

Add the storeUserEmail to the session to identify the customer:

curl --location --request PATCH 'https://secure.vtexfaststore.com/api/sessions' \
--header 'Content-Type: application/json' \
--header 'Cookie: vtex_session={{vtex_session}}' \
--data-raw '{
    "public": {
        "storeUserEmail": {
            "value"<EMAIL_ADDRESS>        }
    }
}'

You should expect this field to be saved at the IndexedDB:

LGTM. You're not using the isAuthenticated field yet, right? Was this your intent?

Yes it was my intent but I will hold this PR because it looks to me that it was actually a bug on the integration side so I´m still checking the necessity to merge this PR and  I´m running some tests on my side and I will only go thought if needed.

After an analysis, this addition was no longer necessary for this reason I am closing this PR.


Export Issue for YDR/YBN

Hi,
Firstly I know how to make a YDR following this tutorial so that's not the issue
https://www.youtube.com/watch?v=YPuKM8vHg-4&t=250s&ab_channel=Quixotic
I had a problem so I reinstalled Blender and Sollumz (using the version from here).
My YDR is make like in the video:
Name
Bound Composite
Bound Geometry VBH
Bound Poly Mesh
Drawable Model
Name model
Now when I want to import my YDR (a simple cube to make it simple), instead of having one YDR I got 3 files:

the YDR
-Bound poly mesh.ybn
-Bound geometry VBH.ybn

When I want to export a YBN same problem, but instead of 1 file YBN I got 2
Pls help me because I can't work on my project haha
Thanks

@Z3USmodding For future, try posting in sollumz discord first for help and alos checking other open issues as same thing here applies on export like issue #684 , sowhen you export dont 'select hierarchy', just need to left click the parent and then export. Its a work around I found in more recent versions on sollumz which is newer than what is used in tutorial videos. and you wont get the extra files upon exporting.

Ok thanks for answer, and I asked on Discord first and ppl told me to go there tha'ts why

@Z3USmodding hey brother have found any fix bcz I'm also having the same problem, and I also found that the problem is with the latest version of sollumz plugins

@Beast-art-des Hey as P-lauski said to me you just have to click on your object and then export, no need to select the whole hierarchy while it was the case with an other sollumz update

@Z3USmodding I did what he said but still it is not exporting ydr, did you export the ydr??if yes, then which version of blender are you using??

Well for me that's ok, I'am using the version you can download here so the last one

@Z3USmodding no I'm not talking about sollumz plugins I'm talking about blender version. Is it 2.8 or 3.5 or 6

Oh the latest one too I downloaded it today


[TypeReconstruction] Dependent types can't have existential as bases.

This basically means the mangling isn't really quite valid, and
given we don't have a full compiler testcase to see what generates
this, we're going to reject this for now.
rdar://problem/38931073

@swift-ci test and merge


location: remove the auth_basic_user_file resource

All it's doing right now is copying a file, but the copy of the file is never referenced by the template.
Fixes #572

@jfryman  you good?

Yup! Sorry, didn't realize you were waiting on me.
:+1:

Yeah I like to get another pair of eyes before I merge straight in. Cheers!


Stemming within textblob

Hello,
I'm new to using this package so I'm sorry if I'm missing something obvious here.
From what I can see, textblob is able to do lemmitization using NLTK's lemmatizer but it is not able to do the same with stemming.
There are times when stemming is the preferred way to go over lemmitization.  Is there a reason this was not included or would this be a valid feature request?

@shawnhind hey I realized this might be a genuine problem. Not sure if 'no stemming' was the intent here, but I wrote a function for it and submitted a PR to @sloria


[BACKPORT] stm32h7 SPI DMA

This is the backported with correct lengths used in DMA setup that was not on original (now closed) PR.  We would not have encountered an issue in our testing as:

nbytes == nwords in our usecase
our buffer allocation is > amount used.

Looks good. Tested on the Holybro Durandal. https://github.com/PX4/Firmware/pull/14483


Something caused shuttle to violently spazz out upon docking

Description
Something caused shuttle to violently spazz out upon docking. Absolutely no idea what went wrong, I think shuttle was rotating rapidly around docking port with which it made joint upon docking.
Reproduction

Dunno! Play game, I guess, this is incredibly rare and I saw this happen only once (but I did see shuttles just clip through station multiple times).

Screenshots

Additional context
Somewhat related with more physics woes: issue #10394.

Without more info it's not getting fixed as it just seems to be a dupe of https://github.com/space-wizards/space-station-14/issues/9055

This issue is so incredibly vague that it is completely unhelpful. Shuttles clipping, spazzing out, and other woes are already well reported. Theres no need to open an issue with no information that could help anyone fix it.

Also to note that whoever was piloting the cargo shuttle was forcing the spin which would've been useful.


add some mqtt payload demo

I struggle to find the mqtt payload to set a disposable pin on my keypad Pro.
Using the test page is fine but having the corresponding generated payload should be nice.
Some automation examples should be nice too.

Following your hints I tried to execute the code in this YAML but unfortunately without luck.
Can you help me ?

action:
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: switchbot/XXXXXXXXXXXX/cmd
      payload: "{ \t\"CommandType\": \"command\", \t\"Command\": \"createKey\", \t\"ParamName\": \"name\", \t\"ParamValue\": \"topolino\" }"
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: switchbot/XXXXXXXXXXXX/cmd
      payload: "{ \t\"CommandType\": \"command\", \t\"Command\": \"createKey\", \t\"ParamName\":  \"type\", \t\"ParamValue\": \"disposable\" }"
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: switchbot/XXXXXXXXXXXX/cmd
      payload: "{ \t\"CommandType\": \"command\", \t\"Command\": \"createKey\", \t\"ParamName\": \"password\", \t\"ParamValue\": \"123456\" }"
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: switchbot/XXXXXXXXXXXX/cmd
      payload: "{ \t\"CommandType\": \"command\", \t\"Command\": \"createKey\", \t\"ParamName\": \"startTime\", \t\"ParamValue\": \"1722770320\" }"
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: switchbot/XXXXXXXXXXXX/cmd
      payload: "{ \t\"CommandType\": \"command\", \t\"Command\": \"createKey\", \t\"ParamName\": \"endTime\", \t\"ParamValue\": \"1722773920\" }"

The input is correctly done. I believe the "button pressed" message is missing.
(For curtains, it's 3 parameters + "button pressed" for a total of 4 messages.
For the keypad, it should be 5 parameters + "button pressed" for a total of 6 messages.)

What happens if you send the following message at the end?
  - service: mqtt.publish
    metadata: {}
    data:
      qos: 0
      retain: false
      topic: switchbot/XXXXXXXXXXXX/cmd
      payload: "{ \t\"CommandType\": \"command\", \t\"Command\": \"createKey\", \t\"ParamName\": \"btn\", \t\"ParamValue\": \"action\" }"

nope
 - service: mqtt.publish     metadata: {}     data:       qos: 0       retain: false       topic: switchbot/XXXXXXXXXXXX/cmd       payload: "{ \t\"CommandType\": \"command\", \t\"Command\": \"createKey\", \t\"ParamName\": \"btn\", \t\"ParamValue\": \"action\" }"

Have you checked the corresponding KeyPad checkbox in the Ingress page device configuration and saved it?

Can you provide a screenshot of the device configuration screen?

After checking and saving, did you start (or restart) the MQTT core service?
Is there any output in the add-on logs?

Can you provide the add-on logs from the start of the add-on (including service start) up until after the MQTT message has been sent?

What is the reason for not using the MQTT integration? (I'd like to know this for future reference.)

[logs.txt](https://github.com/user-attachments/files/16472364/logs.txt)
How I can use the MQTT Integration ? Maybe I don't understand your question ?

The MQTT integration is a standard feature of Home Assistant that communicates with an MQTT broker to discover devices and send commands.
By specifying the broker in the MQTT integration settings screen, you can automatically detect and use devices and entities on Home Assistant through the MQTT Discovery mechanism.
You can find more information and configure it from the following URL:
MQTT Integration

I've reviewed the logs and it appears that the createKey command has been successfully executed 9 times at the following times:
L.33  15:42:00
L.40  16:08:54
L.48  16:09:54
L.51  16:16:39
L.54  16:17:54
L.59  16:24:41
L.86  16:49:35
L.88  16:52:28
L.100  17:25:05
Were all these operations performed from the Ingress page's command test screen? (The log does not differentiate between MQTT messages and the test screen operations.)

this is the screenshot related to a key creation that is successful

If using the mqtt integration, after deleting the key, the operation is unsuccessful

From the second screenshot, it appears that control via MQTT integration is being displayed.
You mentioned that "after deleting the key, the operation is unsuccessful." What specifically leads you to conclude that it is unsuccessful?
My understanding is that MQTT integration button operations do not provide direct feedback in the Home Assistant UI, so there shouldn't be any direct indication of unsuccessful.
Could you provide the logs before and after pressing the "createKey" button (labeled "PREMI" in the screenshot)?
I would expect to see logs similar to the following:
17:25:01 trce: SwitchBotMqttApp.Logics.SwitchBotApiClient[0] Send POST,devices/xxxxxxxxxxxxx/commands
17:25:05 trce: SwitchBotMqttApp.Logics.SwitchBotApiClient[0] Response POST,https://api.switch-bot.com/v1.1/devices/xxxxxxxxxxxxx/commands,{"statusCode":100,"body":{"commandId":"CMD111111111111"},"message":"success"}

If there are no API logs being output, could you check what message was published to the MQTT topic switchbot/{deviceId}/cmd from the MQTT integration?

Dear @hsakoh,
I solved it using this code. There were a lot of escape characters that I think may have confused the API parser.
If you think it may be helpful, you could add this as an example in your documentation.
Thanks a lot!
`action:

service: mqtt.publish
data:
qos: 0
retain: false
payload: >-
{ "CommandType": "command", "Command": "createKey", "ParamName": "name",
"ParamValue": "topolino" }
topic: switchbot/XXXXXXXXXXXX/cmd
service: mqtt.publish
data:
qos: 0
retain: false
topic: switchbot/XXXXXXXXXXXX/cmd
payload: >-
{ "CommandType": "command", "Command": "createKey", "ParamName":
"type", "ParamValue": "a one-time passcode." }
service: mqtt.publish
data:
qos: 0
retain: false
topic: switchbot/XXXXXXXXXXXX/cmd
payload: >-
{ "CommandType": "command", "Command": "createKey", "ParamName":
"password", "ParamValue":"123456789" }
service: mqtt.publish
data:
qos: 0
retain: false
topic: switchbot/XXXXXXXXXXXX/cmd
payload: >-
{ "CommandType": "command", "Command": "createKey", "ParamName":
"startTime", "ParamValue": "1722848965" }
service: mqtt.publish
data:
qos: 0
retain: false
topic: switchbot/XXXXXXXXXXXX/cmd
payload: >-
{ "CommandType": "command", "Command": "createKey", "ParamName":
"endTime", "ParamValue": "1722867782"}" }
service: mqtt.publish
data:
qos: 0
retain: false
topic: switchbot/XXXXXXXXXXXX/cmd
payload: >-
{ "CommandType": "command", "Command": "createKey", "ParamName": "btn",
"ParamValue": "action" }`

I'm glad the issue has been resolved.
I understand that you confirmed the operation by publishing the MQTT message directly. Regarding the parameter name type, the parameter value disposable was incorrect, and the correct value was a one-time passcode as shown in the dropdown list.
This means the value must match exactly with the text in the dropdown list in MQTT integration, which differs from the API input values. If a value not listed in the dropdown is sent in the MQTT message, the command is sent with an empty value.
Have you confirmed the operation from MQTT integration? If the operation seems unreliable, explicitly reselecting the dropdown options might help synchronize the state, especially after restarting the add-on, which can cause the add-on's internal state to be lost.

Regarding the message③, since it is designed to be sent by the MQTT integration, I cannot guarantee that its payload format and other details will be maintained in the future. It is not intended for external direct payload transmission. Therefore, I am not considering documenting it at this time.
Since you have summarized it well enough for those who may encounter this issue, I think that will suffice for now.
If there are no additional questions, I would like to close this issue.

Yes, for sure! You should close the ticket.


Initial infrastructure for building with R.

Initial work for #11

I'm going to merge this and see how it goes.


Stuck

Muaz, good afternoon.
I've been using RTCMultiConnection for some time now. I have the latest version on my server.
But I get a lot of complaint that the webcam freezes, hangs or disconnects.
I did not set any turn servers. Is that it?
I tried to use low bandwidth, but even then, the crashes occur.
            connection.bandwidth = { audio: 20, video: 48 };
            var videoConstraints = { mandatory: { minWidth: 320, maxWidth: 320, minHeight: 250, maxHeight: 250 }, optional: [] };
            connection.mediaConstraints = { video: videoConstraints, audio: true };

When using streaming via Adobe Flash, it worked fine.
Thank you for all your help.
Gabriel

I've been facing same issue, I'm using this [demo]
(https://rtcmulticonnection.herokuapp.com/demos/MultiRTC/) and customizing it as per my requirements but streaming freezes, hangs in between and any user disconnects at any time.
Not sure why this is happening, I've tried joining 4 users in demo too but its freezes there too so I guess its not stable version.
What should I do because my site is having many user and all user streaming their webcam and all other user can see that capturing video.

I've same problem.
My site has a 1-to-1 video chat. It freezes all the time.
It is a pity. Muaz's project is very good, but it has some detail that is bad.


ESP Airlift socket cannot be assigned to HTTPServer

Following assignment causes http sever to fail on start. Is the socket incompatible here ?
The same issue happens in circuit python v7 and v8
from adafruit_esp32spi import adafruit_esp32spi
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_httpserver.server import HTTPServer
...
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
socket.set_interface(esp)
server = HTTPServer(socket)
server.start(esp.pretty_ip(esp.ip_address))

error message:
>>> %Run -c $EDITOR_CONTENT
Creating display
Creating server socket
ESP32 found and in idle mode
Firmware vers. bytearray(b'1.2.2\x00')
MAC addr: ...
...
Connecting to AP...
Connected to jama   RSSI: -27
My IP address is <IP_ADDRESS>
Creating HTTP Server...
starting server..
Traceback (most recent call last):
  File "<stdin>", line 175, in <module>
  File "adafruit_httpserver/server.py", line 91, in start
AttributeError: 'socket' object has no attribute 'bind'
>>>

The adafruit_httpserver library is designed to work with CPython-compatible circuitpython-native sockets (espressif and raspberrypi / Pico W). The sockets exposed by the ESP32SPI NINA firmware are based on Arduino and have a different API (no bind, listen, or accept).
There are examples of HTTP servers for Airlift, for example:
https://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI/tree/main/examples/server

We would like to redo the ESP32SPI library to be API compatible, but haven't done that yet. Maybe it would be a new library, since it would obsolete so much code.

all right, that example mentioned above work fine, thanks


DNS Error when connected to server on Windows ver. 1.8.1

Describe the bug
When I connect to my Outline server on Windows at version 1.8.1, the status in the Outline app is 'Connected', but when I go to any website in the browser – I got DNS Error.
But if I disconnect from the Outline server and connect again – everything will be OK.
I tried to reproduce this bug on my Windows 10 laptop and on Windows Server 2019 at Amazon several times, and each time this bug appears.
If I downgrade to 1.8.0 – all works fine.
To Reproduce
How can the broken behavior be reproduced?
Install Outline 1.8.1 to Windows, add server, connect to it, see status "Connected", go to browser and visit any URL, receive DNS error. IP urls (like http://<IP_ADDRESS>) works good.
Screenshots
Here are 2 screenshots - before connecting and after.

Client System (please complete the following information):

Outline Client Version Windows ver. 1.8.1
Your Operating System: Windows 10 ver. 22H2, Windows Server 2019 Datacenter ver. 1809

The same problem 1.8.1 on Windows Server 2019.
Outline 1.8.0 works perfectly fine.

Can you please re-test this on Windows Client version 1.9.1 and see if it is still occurring? Thanks for your assistance.

1.10.1 the same problem

Thank you for re-testing, and I'm sorry you're having this issue! Please contact us at support.getoutline.org and include the GitHub issue number so that we can better support your needs.
If you haven’t already, check out the Outline Support Site at support.getoutline.org for access to help articles and more.


feature/#684 rename pipeline to sequence

https://app.zenhub.com/workspaces/taipy-613ef328affde6000ff77fb3/issues/gh/avaiga/taipy-core/684

@jrobinAV @trgiangdo
I think the tests are failing due to the pipenv --skip-lock issue that Giang raised yesterday. Can you help clarify this Giang?
Also, it's not possible to generate the pyi file at the moment because we have to merge core first before we run pyi generation to propagate the renaming of PipelineConfig to SequenceConfig.

We need to do something similar to this PR https://github.com/Avaiga/taipy-core/pull/733. That should help fixing the --skip-lock problem

working now thanks @trgiangdo !!!!!