Feature: Generate Typescript functions for Rust commands

Goal: Atomatically generate Typescript functions for Rust commands in Typescript environment
Why: Use Typescript with type checking for Rust commands rather than invoke('some string', somedata)
How:
Assume these Rust commands are available
#[tauri::command]
async fn my_first_custom_command(message: String) -> Result<String, String> {
  Ok("simple type command".into())
}

#[derive(serde::Serialize)]
struct CustomResponse {
  message: String,
  other_val: usize,
}

#[derive(serde::Deserialize)]
struct CustomRequest {
  message: String,
  request: usize,
}

#[tauri::command]
async fn my_second_custom_command(req: CustomRequest, hello: String) -> Result<CustomResponse, String> {
  Ok(CustomResponse {
    message: "custom response".into(),
    other_val: 42,
  })
}

Using Typescript, we can create functions that conform to the Rust commands:
import tauriapi from "@tauri-apps/api";

const { invoke } = tauriapi.tauri;

function my_first_custom_command(message: String): Promise<String> {
  return invoke('my_first_custom_command', {
    message
  })
}

type CustomRequest = {
  message: String;
  request: Number;
}

type CustomResponse = {
  message: String;
  other_val: Number;
}

function my_second_custom_command(req: CustomRequest, hello: String): Promise<CustomResponse>{
  return invoke('my_second_custom_command', {req, hello})
}

export {
  my_first_custom_command,
  my_second_custom_command
}

Now we can call my_first_custom_command and my_second_custom_command with type checking in Typescript.
my_first_custom_command("this must be string")
.then((res) => {
  // res is String
  console.log(res);
});

my_second_custom_command({
  message: "this must be CustomRequest",
  request: 123,
}, "this must be string")
.then((res) => {
  // res is CustomResponse
  console.log(res.message, res.other_val);
});

The steps can be:

Read the tauri::commands function in Rust
Note the input parameters and output type
Generate the corresponding type and function in typescript

Problems that may arises:

Rust commands are written into different files
Rust commands use Struct defined in other files
The Typescript generated file(s) must be re-generated on each rebuild

Simple solution to the above solutions:

Rust commands are placed into a Rust module (src-tauri/src/tauri_commands/*.rs)
Typescript generated files are placed into a seperated modules (tauri_commands/*.tsx)
yarn tauri dev generates Typescript files everytime a file in src-tauri/src/tauri_commands is modified

In discord chat, Denjell suggest that a WASM function can be generated from these Rust commands.
Originated from:
https://discord.com/channels/616186924390023171/731495047962558564/832483720728412192

I just want to mention Aleph-Alpha/ts-rs that does a great job on creating TS from Structs. Maybe something similar could be used in tauri.

I think we could achive it with parse rust codes with AST (or something else) and generate TypeScript definition files like how graphql-code-generator works.

I think we could achive it with parse rust codes with AST (or something else) and generate TypeScript definition files like how graphql-code-generator works.

Just for the inspiration, maybe tRPC architecture is a good place to start: https://trpc.io/

Any status update on this? Just curious where we stand rn

@Cobular The team itself is currently not working on this (otherwise there would be at least some info here). With the upcoming IPC changes for v2 this is further delayed, at least on our side, i still think (or hope) that this could be tackled outside of tauri 🤔

I see! I’ll see if I have time!
On Sep 26, 2022, 06:09 -0700, Fabian-Lars @.***>, wrote:

@Cobular The team itself is currently not working on this (otherwise there would be at least some info here). With the upcoming IPC changes for v2 this is further delayed, at least on our side, i still think (or hope) that this could be tackled outside of tauri 🤔
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.Message ID: @.***>

@FabianLars refers to the potential for community work around this. I have been working on rspc for the last little bit. rspc is designed to be an alternative to tRPC that works with a Rust backend and Typescript frontend. It creates completely end-to-end typesafe APIs and has a plugin so it can easily be used with Tauri. It also has optional React and SolidJS hooks on the frontend which use Tanstack Query under the hood.
It is still very much a work-in-progress project and will likely have breaking changes in the future as I improve the API and introduce new features. Both Spacedrive (my employer) and Twidge have been using the rspc + Prisma Client Rust stack and it has been working pretty well.
If Tauri were ever going to tackle this upstream they could have a look at Specta which is the type exporting system @brendonovich and I made for rspc. Specta differs from ts-rs by its approach. Specta can take in a single type and recursively export all the types it depends on. With ts-rs there isn't an easy way to do that as they have designed the core around the assumption you will export each type individually with a dedicated derive macro. Specta also has a fairly language-agnostic core so it could potentially be used to export Rust types into various other languages although right now Typescript is the main focus. I have been messing around with supporting OpenAPI for example.

@brendonovich and I were talking about this and got to hacking. We managed to get typesafe Tauri commands working on top of Specta. The repository shows an example application that can export the command types to Typescript (and OpenAPI with a few caveats). The code can be found here. It's still a bit of a tech demo but it could be turned into a publishable library or even officially adopted by Tauri if they were interested.

There's another crate to do the generation for this now courtesy of 1password - typeshare - crates.io: Rust Package Registry. If anyone else gets wroking on this beyond Oscar and Brendon's thing, could be helpful!

Might be worth noting that I'm working on https://github.com/tauri-apps/tauri-bindgen now too, it has slightly different behavior and aims to the solutions brought up before, but it can generate typescript files for a given interface too so might be interesting

That looks fantastic! This does indicate it's under heavy development, but how usable would you say this is today? I've just implemented build scripts to provide consistent types from my backend to the Tauri host so I'd I could add this to my project it'd be very helpful.

@Cobular Typeshare is indeed interesting, but would it be applicable for Tauri commands given that they don't support function types? They also have no way to filter out Tauri-specific command arguments. I don't think static analysis would be powerful enough unless you used some sort of enum-based request and response model.
As an aside, I've been working the past couple of days to make Specta more powerful than both ts-rs and Typeshare, and capable of exporting types on its own. Will be interesting to see which solutions the community prefers.

That looks fantastic! This does indicate it's under heavy development, but how usable would you say this is today? I've just implemented build scripts to provide consistent types from my backend to the Tauri host so I'd I could add this to my project it'd be very helpful.

You can use it with two big asterisks:

While the user facing API (i.e. the macros) are pretty stable the internals are absolutely not. And I can't guarantee some of that might leak through.
The async option for the host produces code with lifetime errors atm, soo no async commands.

But: it would be tremendously helpful to have early testers, so by all means try it out please! I will be very responsive in the issues.
Just make sure to pin the crates to specific commits so your code doesn't unexpectedly break

I had the idea of specifying the types directly via the invoke function by overwriting the type of invoke in buildtime generated dts. I was about to begin hacking away with Rust before I decided to look here first.
I imagine that the equivalent to OP's TS with this idea would be;
type CustomRequest = {
  message: String;
  request: Number;
}

type CustomResponse = {
  message: String;
  other_val: Number;
}

type TauriCommands = {
  my_first_custom_command: [
    return: string,
    args: { message: string },
  ],
  my_second_custom_command: [
    return: CustomResponse,
    args: {
      req: CustomRequest,
      hello: string,
    }
}

declare function invoke<T extends keyof TauriCommands>(cmd: T, args: T[1]): Promise<T[0]>;

This adds 0 JavaScript overhead as there isn't a wrapping function call; you call the same invoke as always, it's just more clear to the developer about what it's expecting.
I did make some breaking changes to the invoke type here;

first generic is no longer the returned promise content
this is for readability and to save the TS signature from being too bulky
args parameter is now required
this is to use TS to enforce that all arguments to the function are supplied (including all zero args), which is just convenient

To be non-breaking, the args thing is just a ?, for the generic;
declare function invoke<T extends U[0], U extends keyof TauriCommands>(cmd: U, args: U[1]): Promise<T>;

If we're voting on how generated types for commands are implemented in Tauri (I recognise that's not what we're doing), I vote types only.
We're using Rust for these things specifically because JavaScript is slower and less well equipped for the job.
I would prefer to check back to my Rust files occasionally than to introduce boilerplate code and runtime overhead for the sake of a small bit of DevEx.
I wouldn't be against declare function typings for this if Tauri could come in and find usage, then replace them in compiled output with the actual invoke calls, but no real additional JS should be added; JS is too expensive to waste like this.

I've gotten pretty far in doing this in my own project.
For now I have a commands.rs file with all my Tauri command definitions.
Inside a test I read this file and parse it with syn to build a type definition string.
I have it ignoring State and AppHandle params in a pretty primitive way, in addition to expanding HashMap and Vec types into ts-friendly ones.

src-tauri/srd/commands.rs

#[cfg(test)]
mod test {

    fn rust_type_to_ts(rust_type: &syn::Type) -> String {
        match rust_type {
            syn::Type::Path(type_path) if type_path.qself.is_none() => {
                let ident = &type_path.path.segments.last().unwrap().ident;
                match ident.to_string().as_str() {
                    "str" => "string".to_owned(),
                    "()" => "void".to_owned(),
                    "Result" => {
                        match &type_path.path.segments.last().unwrap().arguments {
                            syn::PathArguments::AngleBracketed(angle_bracketed_data) => {
                                let args: Vec<_> = angle_bracketed_data.args.iter().collect();
                                if let syn::GenericArgument::Type(ty) = args[0] {
                                    rust_type_to_ts(ty)
                                } else {
                                    panic!("Result without inner type")
                                }
                            },
                            _ => panic!("Unsupported angle type: {}", ident.to_string()),
                        }
                    },
                    "Vec" => {
                        match &type_path.path.segments.last().unwrap().arguments {
                            syn::PathArguments::AngleBracketed(angle_bracketed_data) => {
                                if let Some(syn::GenericArgument::Type(ty)) = angle_bracketed_data.args.first() {
                                    format!("Array<{}>", rust_type_to_ts(ty))
                                } else {
                                    panic!("Vec without inner type")
                                }
                            },
                            _ => panic!("Unsupported angle type: {}", ident.to_string()),
                        }
                    },
                    "HashMap" => {
                        match &type_path.path.segments.last().unwrap().arguments {
                            syn::PathArguments::AngleBracketed(angle_bracketed_data) => {
                                let args: Vec<_> = angle_bracketed_data.args.iter().collect();
                                if let syn::GenericArgument::Type(key_ty) = args[0] {
                                    if let syn::GenericArgument::Type(value_ty) = args[1] {
                                        format!("Record<{}, {}>", rust_type_to_ts(key_ty), rust_type_to_ts(value_ty))
                                    } else {
                                        panic!("HashMap without value type")
                                    }
                                } else {
                                    panic!("HashMap without key type")
                                }
                            },
                            _ => panic!("Unsupported angle type: {}", ident.to_string()),
                        }
                    },
                    _ => ident.to_string(),
                }
            },
            syn::Type::Reference(type_reference) => {
                if let syn::Type::Path(type_path) = *type_reference.elem.clone() {
                    let ident = &type_path.path.segments.last().unwrap().ident;
                    match ident.to_string().as_str() {
                        "str" => "string".to_owned(),
                        _ => panic!("Unsupported type: &{}", ident.to_string()),
                    }
                } else {
                    panic!("Unsupported ref type: {}", quote::quote! {#type_reference}.to_string())
                }
            },
            syn::Type::Tuple(tuple_type) if tuple_type.elems.is_empty() => {
                "void".to_owned()
            },
            _ => panic!("Unsupported type: {}", quote::quote! {#rust_type}.to_string()),
        }
    }

    #[test]
    fn list_commands() {
        let contents = std::fs::read_to_string("src/commands.rs").unwrap();
        let ast = syn::parse_file(&contents).unwrap();

        let mut commands = Vec::new();

        for item in ast.items {
            if let syn::Item::Fn(item_fn) = item {
                let tauri_command_attr = item_fn.attrs.iter()
                    .find(|attr| {
                        attr.path().segments.iter().map(|seg| seg.ident.to_string()).collect::<Vec<_>>() == ["tauri", "command"]
                    });

                if tauri_command_attr.is_some() {
                    let command_name = item_fn.sig.ident.to_string();

                    let mut arg_types = Vec::new();
                    for arg in &item_fn.sig.inputs {
                        if let syn::FnArg::Typed(pat_type) = arg {
                            if let syn::Pat::Ident(pat_ident) = &*pat_type.pat {
                                // Filter out State and AppHandle parameters
                                let ty_string = quote::quote! {#pat_type.ty}.to_string();
                                if !ty_string.contains("State") && !ty_string.contains("AppHandle") {
                                    let ts_type = rust_type_to_ts(&pat_type.ty);
                                    arg_types.push(format!("{}: {}", pat_ident.ident, ts_type));
                                }
                            }
                        }
                    }

                    let return_type = if let syn::ReturnType::Type(_, ty) = &item_fn.sig.output {
                        rust_type_to_ts(ty)
                    } else {
                        String::new()
                    };

                    let command_definition = format!("    {}: [\n        return: {},\n        args: {{ {} }}\n    ]", command_name, return_type, arg_types.join(", "));
                    commands.push(command_definition);
                }
            }
        }

        let output = format!("type TauriCommands = {{\n{}\n}};", commands.join(",\n"));
        println!("{}", output);
    }

}

I'm still using ts_rs to generate types for stuff like my ConversationMessagePayload struct
src-tauri/src/payloads.rs
#[derive(Debug, TS, Serialize, Deserialize, Clone)]
#[ts(export, export_to = "../src/lib/bindings/")]
pub struct ConversationMessagePayload {
    #[ts(type="\"system\" | \"user\" | \"assistant\"")]
    pub author: chatgpt::types::Role,
    pub content: String,
}

src/lib/bindings/ConversationMessagePayload.ts
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.

export interface ConversationMessagePayload { author: "system" | "user" | "assistant", content: string, }

but now I'm noticing that I haven't made a ConversationPayload struct for exporting the conversation type to the frontend, and am instead just returning the Conversation struct which is serializable but doesn't have the ts_rs exporting going on.
src-tauri/src/models.rs
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Conversation {
    pub id: uuid::Uuid,
    pub history: Vec<ConversationEventRecord>,
}

in this case it's fine since it's only for debugging
src/lib/Conversation.svelte
        invoke("get_conversation", {
            conversation_id: conversationId,
        }).then((data: any) => {
            console.log("got conversation debug info", data);
        });

it just means that there's an expectation that every type used in the TauriCommands type I'm generating is either a ts built-in or is exported by ts_rs
So right now this output is using a type that doesn't exist on my frontend yet
new_conversation: [
        return: Conversation,
        args: {  }
    ],

Right now my plan is to keep separate Payload types for everything that needs to be passed to the frontend, since the types used in my normal app logic may have properties that don't play nice with Serialize. Idk if I'm being confusing by not using MVC terminology, but it makes sense to me ¯\_ (ツ)_/¯

tl;dr

crawling #[tauri::command] definitions to build a TauriCommands typescript type

the more rustonic way to do this is probably a macro/decorator or something? idk I'm new to rust

TauriCommands type expects that user types are exported using ts_rs
here's my repo: https://github.com/TeamDman/Ehyaioess

Got it working, but then I realized that tauri-specta and tauri-bindgen exist, guess I should read better next time 🤦♂
Here's my updated thing for reference
[dev-dependencies]
quote = "1.0.29"
syn = { version = "2.0.23", features = ["full"] }
indoc = "1.0.3"

#[cfg(test)]
mod test {

    fn rust_type_to_ts(rust_type: &syn::Type) -> String {
        match rust_type {
            syn::Type::Path(type_path) if type_path.qself.is_none() => {
                let ident = &type_path.path.segments.last().unwrap().ident;
                match ident.to_string().as_str() {
                    "str" => "string".to_owned(),
                    "String" => "string".to_owned(),
                    "()" => "void".to_owned(),
                    "Result" => match &type_path.path.segments.last().unwrap().arguments {
                        syn::PathArguments::AngleBracketed(angle_bracketed_data) => {
                            let args: Vec<_> = angle_bracketed_data.args.iter().collect();
                            if let syn::GenericArgument::Type(ty) = args[0] {
                                rust_type_to_ts(ty)
                            } else {
                                panic!("Result without inner type")
                            }
                        }
                        _ => panic!("Unsupported angle type: {}", ident.to_string()),
                    },
                    "Vec" => match &type_path.path.segments.last().unwrap().arguments {
                        syn::PathArguments::AngleBracketed(angle_bracketed_data) => {
                            if let Some(syn::GenericArgument::Type(ty)) =
                                angle_bracketed_data.args.first()
                            {
                                format!("Array<{}>", rust_type_to_ts(ty))
                            } else {
                                panic!("Vec without inner type")
                            }
                        }
                        _ => panic!("Unsupported angle type: {}", ident.to_string()),
                    },
                    "HashMap" => match &type_path.path.segments.last().unwrap().arguments {
                        syn::PathArguments::AngleBracketed(angle_bracketed_data) => {
                            let args: Vec<_> = angle_bracketed_data.args.iter().collect();
                            if let syn::GenericArgument::Type(key_ty) = args[0] {
                                if let syn::GenericArgument::Type(value_ty) = args[1] {
                                    format!(
                                        "Record<{}, {}>",
                                        rust_type_to_ts(key_ty),
                                        rust_type_to_ts(value_ty)
                                    )
                                } else {
                                    panic!("HashMap without value type")
                                }
                            } else {
                                panic!("HashMap without key type")
                            }
                        }
                        _ => panic!("Unsupported angle type: {}", ident.to_string()),
                    },
                    _ => ident.to_string(),
                }
            }
            syn::Type::Reference(type_reference) => {
                if let syn::Type::Path(type_path) = *type_reference.elem.clone() {
                    let ident = &type_path.path.segments.last().unwrap().ident;
                    match ident.to_string().as_str() {
                        "str" => "string".to_owned(),
                        _ => panic!("Unsupported type: &{}", ident.to_string()),
                    }
                } else {
                    panic!(
                        "Unsupported ref type: {}",
                        quote::quote! {#type_reference}.to_string()
                    )
                }
            }
            syn::Type::Tuple(tuple_type) if tuple_type.elems.is_empty() => "void".to_owned(),
            _ => panic!(
                "Unsupported type: {}",
                quote::quote! {#rust_type}.to_string()
            ),
        }
    }

    #[test]
    fn build_command_type_definitions() {
        let contents = std::fs::read_to_string("src/commands.rs").unwrap();
        let ast = syn::parse_file(&contents).unwrap();

        let mut commands = Vec::new();

        for item in ast.items {
            if let syn::Item::Fn(item_fn) = item {
                let tauri_command_attr = item_fn.attrs.iter().find(|attr| {
                    attr.path()
                        .segments
                        .iter()
                        .map(|seg| seg.ident.to_string())
                        .collect::<Vec<_>>()
                        == ["tauri", "command"]
                });

                if tauri_command_attr.is_some() {
                    let command_name = item_fn.sig.ident.to_string();

                    let mut arg_types = Vec::new();
                    for arg in &item_fn.sig.inputs {
                        if let syn::FnArg::Typed(pat_type) = arg {
                            if let syn::Pat::Ident(pat_ident) = &*pat_type.pat {
                                // Filter out State and AppHandle parameters
                                let ty_string = quote::quote! {#pat_type.ty}.to_string();
                                if !ty_string.contains("State") && !ty_string.contains("AppHandle")
                                {
                                    let ts_type = rust_type_to_ts(&pat_type.ty);
                                    arg_types.push(format!("{}: {}", pat_ident.ident, ts_type));
                                }
                            }
                        }
                    }

                    let return_type = if let syn::ReturnType::Type(_, ty) = &item_fn.sig.output {
                        rust_type_to_ts(ty)
                    } else {
                        String::new()
                    };

                    let command_definition = format!(
                        "    {}: {{\n        returns: {},\n        args: {{ {} }}\n    }}",
                        command_name,
                        return_type,
                        arg_types.join(", ")
                    );
                    commands.push(command_definition);
                }
            }
        }

        // build file contents
        let warning_header = "// THIS FILE IS AUTO-GENERATED BY CARGO TESTS! DO NOT EDIT!";
        let invoke_import = "import { invoke as invokeRaw } from \"@tauri-apps/api\";";
        let tauri_commands = format!("type TauriCommands = {{\n{}\n}};", commands.join(",\n"));
        let invoke_fn = indoc::indoc! {"
            export function invoke<T extends keyof TauriCommands>(cmd: T, args: TauriCommands[T][\"args\"]): Promise<TauriCommands[T][\"returns\"]> {
                return invokeRaw(cmd, args);
            }
        "};
        let output = format!(
            "{}\n\n{}\n\n{}\n\n{}",
            warning_header, invoke_import, tauri_commands, invoke_fn
        );

        // dump to file
        std::fs::create_dir_all("../src/lib/bindings").unwrap();
        let definitions_file =
            std::fs::File::create("../src/lib/bindings/tauri_commands.d.ts").unwrap();
        std::io::Write::write_all(
            &mut std::io::BufWriter::new(definitions_file),
            output.as_bytes(),
        )
        .unwrap();
    }
}

example output
// THIS FILE IS AUTO-GENERATED BY CARGO TESTS! DO NOT EDIT!

import { invoke as invokeRaw } from "@tauri-apps/api";

type TauriCommands = {
    list_conversation_titles: {
        returns: Record<string, string>,
        args: {  }
    },
    get_conversation: {
        returns: Conversation,
        args: { conversation_id: string }
    },
    get_conversation_title: {
        returns: string,
        args: { conversation_id: string }
    },
    get_conversation_messages: {
        returns: Array<ConversationMessagePayload>,
        args: { conversation_id: string }
    },
    new_conversation: {
        returns: Conversation,
        args: {  }
    },
    set_conversation_title: {
        returns: void,
        args: { conversation_id: string, new_title: string }
    },
    new_conversation_user_message: {
        returns: void,
        args: { conversation_id: string, content: string }
    },
    new_conversation_assistant_message: {
        returns: void,
        args: { conversation_id: string }
    },
    list_files: {
        returns: Array<string>,
        args: {  }
    }
};

export function invoke<T extends keyof TauriCommands>(cmd: T, args: TauriCommands[T]["args"]): Promise<TauriCommands[T]["returns"]> {
    return invokeRaw(cmd, args);
}

@TeamDman Was just about to recommend looking at tauri-specta haha. It does the 'macro/decorator or something' you mentioned and works with any type that you derive(specta::Type) for, not just hardcoded ones.
On that note, I feel like this pretty much solved. While there's no officially recommended solution yet, there's plenty out there to generate TypeScript bindings to Tauri commands.
Rust -> TypeScript
tauri-specta is your crate. It utilises specta to extract type information via the Type trait, and then generates individual functions that mirror your Tauri commands, along with all custom types that those commands take as args and return.
It's the easiest answer to 'how do I generate TypeScript bindings from Rust'.
Schema -> Rust + TypeScript
tauri-bindgen allows you to define your commands + custom types in *.wit files, and then generate both Rust for you to implement your commands, and many guest languages as bindings for your frontend. It allows for a more centralised approach to defining your commands than just using whatever is defined in Rust.
Other Solutions

rspc is a more general-purpose router modelled after tRPC that supports request/response via queries and mutations, subscriptions for sending event streams from backend -> frontend, and middleware. It can generate TypeScript bindings via specta and is server-agnostic, meaning you can plug it into axum, actix-web, or even Tauri like we do in Spacedrive. It's similar to Tauri's upcoming IPC router, just with more complexity and portability.

If there's any other good solutions I'm missing then please let me know!

Goal: Atomatically generate Typescript functions for Rust commands in Typescript environment
Why: Use Typescript with type checking for Rust commands rather than invoke('some string', somedata)
How:
Assume these Rust commands are available
#[tauri::command]
async fn my_first_custom_command(message: String) -> Result<String, String> {
  Ok("simple type command".into())
}

#[derive(serde::Serialize)]
struct CustomResponse {
  message: String,
  other_val: usize,
}

#[derive(serde::Deserialize)]
struct CustomRequest {
  message: String,
  request: usize,
}

#[tauri::command]
async fn my_second_custom_command(req: CustomRequest, hello: String) -> Result<CustomResponse, String> {
  Ok(CustomResponse {
    message: "custom response".into(),
    other_val: 42,
  })
}

Using Typescript, we can create functions that conform to the Rust commands:
import tauriapi from "@tauri-apps/api";

const { invoke } = tauriapi.tauri;

function my_first_custom_command(message: String): Promise<String> {
  return invoke('my_first_custom_command', {
    message
  })
}

type CustomRequest = {
  message: String;
  request: Number;
}

type CustomResponse = {
  message: String;
  other_val: Number;
}

function my_second_custom_command(req: CustomRequest, hello: String): Promise<CustomResponse>{
  return invoke('my_second_custom_command', {req, hello})
}

export {
  my_first_custom_command,
  my_second_custom_command
}

Now we can call my_first_custom_command and my_second_custom_command with type checking in Typescript.
my_first_custom_command("this must be string")
.then((res) => {
  // res is String
  console.log(res);
});

my_second_custom_command({
  message: "this must be CustomRequest",
  request: 123,
}, "this must be string")
.then((res) => {
  // res is CustomResponse
  console.log(res.message, res.other_val);
});

The steps can be:

Read the tauri::commands function in Rust
Note the input parameters and output type
Generate the corresponding type and function in typescript

Problems that may arises:

Rust commands are written into different files
Rust commands use Struct defined in other files
The Typescript generated file(s) must be re-generated on each rebuild

Simple solution to the above solutions:

Rust commands are placed into a Rust module (src-tauri/src/tauri_commands/*.rs)
Typescript generated files are placed into a seperated modules (tauri_commands/*.tsx)
yarn tauri dev generates Typescript files everytime a file in src-tauri/src/tauri_commands is modified

In discord chat, Denjell suggest that a WASM function can be generated from these Rust commands.
Originated from: https://discord.com/channels/616186924390023171/731495047962558564/832483720728412192

I just started using Tauri today and would love to see this in action. Has anyone done this?

@michTheBrandofficial Please see Brendonovich's comment right above yours... tauri-specta is currently the blessed solution.

Why is protocol buffers not mentioned here?


fix: update package.json to match LICENSE-MIT

Fixes #120

+1, can we merge this and republish? @maintainers, let me know if we I can help with this package


Known Issue: Browser access blocked by blank screen with gray bar

ISSUE TYPE

Known Issue

AS3 BUILD/ VERSION

All versions

BIGIP VERSION

All supported versions

SUMMARY

After using the DELETE method to remove an AS3 configuration, you are unable to access the BIG-IP configuration utility. In your browser window, you see only a gray screen with a dark gray bar.
WORKAROUND
Use one of the following workarounds:

Return to your API client and re-deploy the tenant that was previously configured. This should unlock the web interface.
Login to the BIG-IP CLI shell and restart the tomcat daemon by typing bigstart restart tomcat.

We're running into this quite often, it looks like it's not affecting just AS3 but also lbaasv2 configurations.
As this issue was created over a year ago, I wonder if there are any plans for a fix..


fix issue #185, pre-create manifests directory

This fixes issue #185.  This pre-creates manifests directory on manifest and agent in case there is ever a time where they do not have manifest files.

Hi @anhowe, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

It looks like you're a Microsoft contributor (Anthony Howe). If you're full-time, we DON'T require a Contribution License Agreement. If you are a vendor, please DO sign the electronic Contribution License Agreement. It will take 2 minutes and there's no faxing! https://cla.microsoft.com.

TTYL, MSBOT;

Go for it. I approved already.
On Jan 24, 2017 4:22 PM, "anhowe"<EMAIL_ADDRESS>wrote:

@anhowe commented on this pull request.
In parts/kubernetesagentcustomdata.yml
https://github.com/Azure/acs-engine/pull/207:

@@ -13,6 +13,7 @@ runcmd:

systemctl restart docker
/usr/bin/curl -sSL --retry 12 --retry-delay 10 https://storage.googleapis.com/kubernetes-release/release/{{{kubectlVersion}}}/bin/linux/amd64/kubectl > /usr/local/bin/kubectl
chmod +x /usr/local/bin/kubectl
+- /bin/mkdir -p /etc/kubernetes/manifests

fixed
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/Azure/acs-engine/pull/207, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAT9dMQtkTzlG7BpQFfG4npw-2jSp4VJks5rVpXYgaJpZM4Ls8jC
.

One more suggestion @anhowe. If your commit message or pull request text
says "Fixes #0" then the associated Issue is closed automatically with a
link to the PR.
As is now, you're closing without manually or automatically linking to the
PR so it's hard for people to discover where or how their issue was fixed.
On Jan 24, 2017 4:24 PM, "Cole Mickens"<EMAIL_ADDRESS>wrote:

Go for it. I approved already.
On Jan 24, 2017 4:22 PM, "anhowe"<EMAIL_ADDRESS>wrote:

@anhowe commented on this pull request.
In parts/kubernetesagentcustomdata.yml
https://github.com/Azure/acs-engine/pull/207:

@@ -13,6 +13,7 @@ runcmd:

systemctl restart docker
/usr/bin/curl -sSL --retry 12 --retry-delay 10 https://storage.googleapis.com/kubernetes-release/release/{{{kubectlVersion}}}/bin/linux/amd64/kubectl > /usr/local/bin/kubectl
chmod +x /usr/local/bin/kubectl
+- /bin/mkdir -p /etc/kubernetes/manifests

fixed
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/Azure/acs-engine/pull/207, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAT9dMQtkTzlG7BpQFfG4npw-2jSp4VJks5rVpXYgaJpZM4Ls8jC
.


[Enhance request] Put x numbers to populate the same thing x times.

Right now, I have to add the motor 5 times and the LED 8 times manually.
Is there a way to just specify '8 x device,' and it will automatically list them with the names I choose, like 'led_', generating led_0, led_1, and so on?
This would save me so much time.

on this one, when you add new device instance just prepoulate it with what makes sense and let user edit it instaed of starting from scratch. FEAGI index can be incremented and other properties can be copied. the label can be augmented with the dev index


feat(#1816): width property for container

This PR for https://github.com/GovAlta/ui-components/issues/1816 adds a width property to the Container component. It has two values:

Name
Description
Screenshot

Full
Expand to fit available horizontal width (default)

Content
Shrink to width of content.

[x] I have run a build locally.
[x] I have ran unit tests locally.
[x] I have tested the functionality.

I updated the unit tests with the width property and they pass:

I tested the changes on latest Chrome...

Latest Edge...

Latest Firefox...

Latest Safari...

When GoAAccordion inside , this display is not correct
  <GoAContainer width="content">
  <GoAAccordion heading="Heading" headingSize="medium">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
  </GoAAccordion>
  </GoAContainer>

When GoAGrid inside , this display is not correct
  <GoAContainer width="content">
    <GoAGrid minChildWidth="12ch">
      <GoAFormItem
        label="Given name"
        id="givenName"
      >
        <GoAInputText name="givenName" maxLength={50} onChange={() => { }} />
      </GoAFormItem>
      <GoAFormItem
        label="Surname"
        id="surname"
      >
        <GoAInputText
          name="surname"
          onChange={() => { }}
          maxLength={50}
        />
      </GoAFormItem>
    </GoAGrid>
  </GoAContainer>

@lizhuomeng71 I spent some time exploring why goa-grid didn't work as you expect.
When goa-container has a width of content, It collapses to the width of the child. For a goa-grid, this width is equal to a column's minimum width. The column width can either be...

The width specified in the minChildWidth property
0px, if no minChildWidth is set

In your above example, you set the minChildWidth to 12ch. The amount is too narrow for the inputs, which have a default width of 30ch. When I update minChildWidth to 30ch then I see the following:

This is what I expect. If they want a two-column layout, they should wrap the goa-grid in an element with a set width.
Does that make sense?  I'm happy to chat about it if you have any questions.

Hi @bdfranck , thanks for the update, there is also another comment regarding GoAAccordion

@lizhuomeng71 Yup! The problem is that the .goa-accordion width shrinks to 0 in this situation regardless of it's children. I'm still not sure why. 🤔

Removing this line of CSS in accordion fixes the issue...
https://github.com/GovAlta/ui-components/blob/dc4066b2d67b0491558839683d73c8bb3586bb85/libs/web-components/src/components/accordion/Accordion.svelte#L121-L123

...but we need to keep that line for content queries in the Accordion component. I'll keep exploring.

@lizhuomeng71 Here's my best explanation of what is going on:
Because .goa-container has container-type: inline-size, it cannot be sized by the width of its children. It effectively has a minimum width of 0.
You should see this issue when you put an accordion in a flexbox with flex-shrink.
<div style="display: flex; flex-shrink: 1;">
  <goa-accordion headingsize="small" heading="Accordion heading">
    This is some test content within the accordion.
  </goa-accordion>
</div>

For example, you can see this issue when you put an accordion in a goa-block:
<goa-block>
  <goa-accordion headingsize="small" heading="Accordion heading">
    This is some test content within the accordion.
  </goa-accordion>
</goa-block>

I'm not sure if we want to fix this or just advise people to put the accordion in a sized element for these situations. I'll write a bug to start the discussion.

@lizhuomeng71 I wrote a bug for the issue you discovered:
https://github.com/GovAlta/ui-components/issues/1864
Anything else?

Hi Team, issue is verified on Chrome and Firefox, issue raised is identified as non-issues, Move ticket to Ready for Review

:tada: This PR is included in version 1.17.0-alpha.53 :tada:
The release is available on:

npm package (@alpha dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

:tada: This PR is included in version 4.17.0-alpha.26 :tada:
The release is available on:

npm package (@alpha dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

:tada: This PR is included in version 1.21.0 :tada:
The release is available on:

npm package (@latest dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

:tada: This PR is included in version 4.21.0 :tada:
The release is available on:

npm package (@latest dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

:tada: This PR is included in version 3.0.0-alpha.4 :tada:
The release is available on:

npm package (@alpha dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

:tada: This PR is included in version 3.0.3 :tada:
The release is available on:

npm package (@latest dist-tag)
GitHub release

Your semantic-release bot :package::rocket:


bump dependencies

especially arrow, with old lexical-core dependency with multiple soundness issues https://github.com/advisories/GHSA-2326-pfpj-vx3h.
Also bumped ratatui and adapted to new API based on deprecation warnings.

@jqnatividad Thanks!


Debug trace added for VMI no connection issue

Signed-off-by: Varsha Kaverappa<EMAIL_ADDRESS>Change-Id: I20fb11581cab6a750b092173ba61aeae47e9ab52

Can one of the admins verify this patch?

add to approvelist


post-processing of box detector

hi，
I'm very interested in the post-processing algorithm, but I can't understand it through the code.
Could you please give me some information about it?

Hi. @outmanzm
I'm busy with other projects, but I'll give you a brief explanation as soon as possible.

@geonm Looking forward to it! Thank you very much.

Hi @geonm. Are you free now ? Could you please explain to me ? Thank you in advance.

Still busy but...
Sure!
I will explain the post processing with figures over the weekend.
Please stay tuned! 😄

I'll publish a technical report about the post processing.
Please wait a little longer.

Hi, where can we access the related technical report?

@Babylonehy
I briefly summarized the post-processing for the box detector.
See https://github.com/navervision/mlsd/issues/20 first.
Now I'm working on another project heavily. Need more time...


Optimize vector deserialization in RuntimeObject

Summary

Optimize vector deserialization in RuntimeObject
Add a benchmark for large object transferring.

related issue: #2678
Performance

Given the following Move struct with 100000 elements, the deserialization time in RuntimeObject::load descreased from 4861.5us to 13.7us.

  struct VecU8 has key, store {
    values: vector<u8>
  }

benchmark for bench_tx_exec/l2_tx_transfer_large_object:

This PR change third part move crate, cc @steelgeek091


Command "which" is not installed by default

Description
When running sct_install the script checks that some dependencies are installed on the OS before proceeding with the installation. To look up for those dependencies which needs to be installed.
It seems that some OS don't have which installed by default, so the installation fails.
Steps to Reproduce

# in Terminal
docker pull centos:latest
docker run -it centos:latest
# in docker container
yum -y install git bzip2 gcc

git clone https://github.com/neuropoly/spinalcordtoolbox.git sct
cd sct
yes | ./install_sct

Output:
[root@82fe36d77cef sct]# which wget
bash: which: command not found

Expected behavior: Installation completes successfully

@gmotzespina why is step 0 needed?

also: i don't think this issue is specific to CentOS7 (the docker container is curated, and other CentOS7 distros do have which installed). Moreover, this could also happen with distros other than CentOS7.
So: we should generalize this issue, and simply check if "which" is installed at the beginning of the installer. If not, we inform the user.
Regarding the docker doc: you can simply add which install on the docker container
thanks 👍

@jcohenadad I've updated the issue to be more general. I'll add on the docs the which installation step.

@jcohenadad I did the same with curl since it wasn't specified on the docs and it was a step I needed to do before being able to proceed with the installation.

Closing as which was replaced with command -v in https://github.com/neuropoly/spinalcordtoolbox/pull/3102.


Active Directory Site

Site is not for Azure AD, it is for Active Directory.

@kojinak : Thanks for your contribution! The author, @PatAltimore, has been notified to review your proposed change.

@kojinak Thank you for the fix. You're right. The sentence should say "Active Directory" instead of "Azure AD".
Thanks,
Pat
#sign-off


Bump kv-asset-handler to latest release

What this PR solves / how to test:
Bumps kv-asset-handler to the latest v0.3.0 release, no breaking changes, just fixes.
Author has included the following, where applicable:

[ ] Tests
[x] Changeset (Changeset guidelines)

Reviewer is to perform the following, as applicable:

Checked for inclusion of relevant tests
Checked for inclusion of a relevant changeset
Checked for creation of associated docs updates
Manually pulled down the changes and spot-tested

I believe we achieved this when we brought the kv-asset-handler over to the workers-sdk monorepo.

@petebacondarwin the files look unchanged to me in the current main branch...

OK if you could rebase on main then we can see the diff.

I updated it so that it uses the workspace:* syntax in all cases...


Not able to post the ad from the kijiji-manager

I am trying to post an ad from the manager, but it goes to inactive. However, when I try to post the ad from the website with the same account, it does not go inactive. What do you think the reason could be @jackm?
I can provide you with logs if you want any.

I have had this issue for a few weeks also. Any update?

I tried this today. After posting an ad via kijiji-manager, the ad was shown in the "inactive" tab on the Kijiji site (with a note on it saying that it was under review). After about an hour the ad became active.
This could be some new detection method that Kijiji is using to review/delay ads that it suspects where posted from something other than the official site or official app.

getting same issue

Had the issues for months, gave up on this one and found something else
that does that same thing inside Chrome
On Sun, Apr 21, 2024 at 03:49 zjavaid1981 @.***> wrote:

getting same issue
—
Reply to this email directly, view it on GitHub
https://github.com/jackm/kijiji-manager/issues/65#issuecomment-2067945935,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AW2MOU66ILF34LGILL56GXDY6NVRHAVCNFSM6AAAAABBCN62N2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANRXHE2DKOJTGU
.
You are receiving this because you commented.Message ID:
@.***>

What’s the alternative? Isn’t that paid now ?


Roll engine to 336c23f846a2683d043d3a3b504ae27eaf447efc

336c23f84 Remove //flutter/glue and use FML directly. (#5862)
7d17da76d Package Skia licenses into a separate file from other third party libraries (#5861)
d2d8bf394 Pass touch events to embedded Android views with dispatchTouchEvents.
216908652 Synthesize Android MotionEvents with the long form obtain method.
0b4432769 Roll src/third_party/skia 396661825f45..1c94a8fabed7 (8 commits) (#5859)
f50e218d9 Rename clip mode to clip behavior (#5853)
42bd86d6d Make the virtual display's presentation window non focusable. (#5845)
a726e1d85 Roll src/third_party/skia c062b6be5a01..396661825f45 (3 commits) (#5857)
3fa83d2d2 Roll src/third_party/skia 15020ea2cf44..c062b6be5a01 (1 commits) (#5856)
75ad43954 Roll src/third_party/skia 4c7a750e5543..15020ea2cf44 (1 commits) (#5855)
5cd8b4530 Roll src/third_party/skia 75e5406be66a..4c7a750e5543 (2 commits) (#5854)
e12b52841 Roll src/third_party/skia b8eeb808d84f..75e5406be66a (17 commits) (#5852)
5bc1e68b6 Remove check_roll from Travis (#5846)

Another roll is is progress.


Unable to login or register to the server

On the website homepage: the registered users is 0. When I tried to login, there was no response. If I try to sign up, it will not reply as well.

Thanks for letting us know. We'll look into that.

This was related to a hardware problem.


Remove downloaded pins on logout

This should make it so that when the user logs out or their token expires that the pins are cleared that they previously had downloaded. (But will keep local locations)

 Remove pins after expiry

Looks like I cannot merge now


ENH: add isin, setdiff1d

These functions look like the most obvious candidates for this library from scikit-learn: https://github.com/scikit-learn/scikit-learn/blob/439ea045ad44e6a09115dc23e9bf23db00ff41de/sklearn/utils/_array_api.py#L931-L982
cc @omarmanzoor @ogrisel @betatim

One problem is that these functions make use of device from array-api-compat. Either we need to restrict support in this library to array objects with the device attribute, or we vendor (copy) device and the functions it calls from array-api-compat.

I would propose isin for inclusion in the standard.

any thoughts on setdiff1d @asmeurer ?

I've never even heard of that function before. I guess if it has a lot of usage it could be proposed too, but otherwise I would assume it's a more niche function that would be appropriate. Also, isn't it straightforward to implement in terms of isin if that were added (though perhaps inefficiently)?

In scikit-learn they implement both in terms of in1d

I'd also say that setdiff1d is too niche to consider for the standard. Adding it to array-api-extra seems like a better option.


Maybe make ConcoctionsTest faster

Tweaked Concoction Test.  Faster but still a candidate for moving to DebugDatabase.  Feedback welcomed.

So it seems that Windows is getting more heap space than Ubuntu?
And not even "my" test...
Caused by: java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.regex.Matcher.(Matcher.java:247)
at java.base/java.util.regex.Pattern.matcher(Pattern.java:1134)
at net.sourceforge.kolmafia.Modifiers.parseModifiers(Modifiers.java:1923)
at net.sourceforge.kolmafia.Modifiers.getModifiers(Modifiers.java:1895)
at net.sourceforge.kolmafia.DebugModifiers.allModifiers(DebugModifiers.java:127)
at net.sourceforge.kolmafia.textui.command.ModifierListCommand.run(ModifierListCommand.java:23)
at net.sourceforge.kolmafia.KoLmafiaCLI.doExecuteCommand(KoLmafiaCLI.java:458)
at net.sourceforge.kolmafia.KoLmafiaCLI.executeCommand(KoLmafiaCLI.java:419)
at net.sourceforge.kolmafia.KoLmafiaCLI.executeLine(KoLmafiaCLI.java:338)
at net.sourceforge.kolmafia.KoLmafiaCLI.executeLine(KoLmafiaCLI.java:225)
at net.sourceforge.kolmafia.KoLmafiaCLI$CommandProcessorThread.run(KoLmafiaCLI.java:160)
at net.sourceforge.kolmafia.KoLmafiaCLI.listenForCommands(KoLmafiaCLI.java:220)
at net.sourceforge.kolmafia.textui.command.CallScriptCommand.call(CallScriptCommand.java:217)
at net.sourceforge.kolmafia.textui.command.CallScriptCommand.run(CallScriptCommand.java:34)
at net.sourceforge.kolmafia.CustomScriptTest.testScript(CustomScriptTest.java:55)

After much thought I moved the compareTo contract testing to a checkconcoctions cli command that can be invoked on demand.  It doesn't do much for test coverage but doing so reduces test running time.  It also makes sense that someone changing concoctions.txt might need the check but it was a lot of effort for a test being run all of the time.
PR with the new command hasn't been pushed yet but there were some things worth keeping that crept into this PR so...


Function call not compatible with 702

Cannot use functional methods in CALL FUNCTION:
https://github.com/abapGit/abapGit/blob/887e7dd3321dfd913127a2d7e035f18e9225e80f/src/ui/zcl_abapgit_gui_router.clas.abap#L733-L738

of course... it's nice to support 702 but it's also a pain. thanks for fixing and having Lars create a rule for it so I don't mess it up again 😄


kedro-airflow: revise Airflow deployment manual

Description
The Airflow Deployment Manual appears to require updates:

The manual should be fully operational, with all outdated information removed to prevent confusion.
Future of the kedro-airflow-k8s plugin: There needs to be a decision on whether to continue recommending the kedro-airflow-k8s plugin, especially since it's noted to be compatible with kedro versions less than 0.18.
My suggestion is to move away from recommending the astro-airflow-iris starter, considering it's outdated and not specifically required for running Kedro projects on Airflow with Astronomer. It may be clearer for users to start with the standard spaceflights-pandas starter available through the kedro new command with options [1-5], ensuring a more streamlined and up-to-date starting point.
Current Strategy:

The general strategy to deploy a Kedro pipeline on Apache Airflow is to run every Kedro node as an Airflow task while the whole pipeline is converted into a DAG for orchestration purpose. This approach mirrors the principles of running Kedro in a distributed environment.

should be discussed and confirmed, as it has several drawbacks regarding the approach of running a new Kedro session for each node:

it can be time consuming
it does not accommodate Memory datasets, necessitating their specification and storage within the dataCatalog. This limitation should be explicitly addressed in the docs to ensure clarity for users.

If strategy will be confirmed it might be advantageous to enhance the kedro-airflow plugin with to not only generate the DAG but also create an Airflow configuration folder, including a tailored version of config.yml that incorporates all MemoryDatasets.

Given the known issues with default logging via the Rich library, the manual should include a section advising on switching from Rich to Console logging, complete with detailed instructions to facilitate this change and ensure DAG operability.
Guidance on automatically transferring files from the Airflow container back to the user's local folder maybe benefit users.
Incorporating a section that outlines steps for deploying kedro Airflow project to cloud services such as AWS, Azure, and Google Cloud, AstroCloud.

The outcome of this ticket is to fix 1,2,3,5 and 6. The idea is to improve the existing documentation and make it run properly. There other points mentioned here will be tackled in separate tickets.

Comments 1, 3, 5, and 6 have been addressed in https://github.com/kedro-org/kedro/pull/3792. Follow-up tickets have been created for comments 2 and 7 at https://github.com/kedro-org/kedro-plugins/issues/652 and https://github.com/kedro-org/kedro-plugins/issues/651 respectively. Regarding the changes in deployment strategy proposed by comment 4, I currently do not have any ideas for modifications. However, we should discuss the deployment strategy during a Technical Design session to share knowledge, explore possibilities, and confirm the current strategy.

Ticket for 4 probably #2058?


Deployments should have resource objects with resource metadata

A deployment needs to have information about the resources created:

status of resource (created, failed, aborted)
error messages
RESTful identifier/link to the actual resource created
name, type, properties

These (and errors in #79) could be part of Deployment, or part of a Manifest. If they are part of a Manifest, you would have one stop shop for: input, fully expanded low level config as well as the output [resources/errors]. Unless I hear strong arguments against putting them there, I'd like to at least take a whack at putting them there.


Persistent Notifications Show on All Views

Home Assistant release (hass --version): 0.40.0
Python release (python3 --version): Python 3.5.2
Component/platform: Persistent Notification
Description of problem:
When a persistent notification with an ID is created, it shows on ALL views, instead of just the views where I have added persistent_notification.X entities. This is a regression.
For example, if I call persistent_notification/create with:
{
  "notification_id": "2",
  "title": "Sample notification",
  "message": "This is a sample text"
}

it shows on all views (I have 3), not just the only one where I have added  persistent_notification.2. I expect this to happen only if there is no notification_id. I have automation creating notifications with ID numbers and have purposefully added persistent_notification.X entities to only one view, the one where I want to see them.
** Configuration **
configuration.yaml:
group: !include group.yaml

group.yaml:
default_view:
  view: yes
  entities:
    - group.bedroom_thermostat
    - group.kitchen_media
    - group.kitchen
    - group.bedroom_lights
    - group.people
    - group.current_weather
    - persistent_notification.2
    - persistent_notification.3

System:
  view: yes
  entities:
    - group.measurements
    - group.toggles

Weather:
  view: yes
  entities:
    - group.currently
    - camera.recent_radar
    - group.forecast

Additional info:
This broke some time between 0.28 and v.0.36.1 (helpful I know): https://community.home-assistant.io/t/id-bound-persistent-notifications-show-on-all-views/10351

This is a feature....not a bug :)
Persistent notifications appear on all tabs so that they are not missed. There was some confusion about this and ppl missed those notifications and then @balloob added this feature.

I can accept that. Do you have a suggestion on an alternate way to display a couple sentences? I was using it for the day's text forecast.

You can use something like:
    - service: persistent_notification.create
      data:
        title: "Update Available"
        message: >
          Home Assistant {{ states('updater.updater') }} is available, please [update](https://home-assistant.io/getting-started/installation-raspberry-pi-all-in-one/#upgrading).
        notification_id: "update_available"

The complete automation is here

Right, but won't that show on every view? I just want it on one

@arsaboo is right and this is by design.

Wouldn't it be possible to implement the following?

show a persistent notification on all views by default
show a persistent notification only on the view(s) selected by the user in their view configuration (as it then becomes their choice and they're aware of this behaviour)


missing components on dotnet based project

Hi,
When I try to run cdxgen against the dotnet source code, I see there are some components that are part of the solution missing in the sbom file. these components are referred to in the code and also part of the csproj reference list. The highlighted components are not included in the SBOM and all other components are part of the SBOM.

@visagansanthanam-unisys, was the solution built prior to invoking cdxgen? Could you check for the presence of projects.assets.json?

@prabhu so the solution is not built prior to invoking cdxgen and it does not have projects.assets.json. How are the other components identified in this case?

@visagansanthanam-unisys, we parse the csproj file if projects.assets.json is not available. This is explained in the footnotes in the readme.

[3] - Perform dotnet or nuget restore to generate project.assets.json. Without this file, cdxgen would not include indirect dependencies.

@prabhu I understand about including indirect dependencies. but what I reported is missing direct dependencies which are part of the csproj file.  cdxgen tool is identifying some of the components on the project references and misses others.

@visagansanthanam-unisys would you be able to share the csproj file? Suspecting those entries with only .dll is getting missed out

@prabhu attached zip file has the csproj file
Server-dependencies.zip

@prabhu can you help with the instruction for running cdxgen directly using souce code.

@visagansanthanam-unisys The file you would be calling is bin/cdxgen.js. You can use the usual options or --help by calling this file.

@cerrussell is there any action pending from me on this bug?

@visagansanthanam-unisys, no one is currently working on this. Could you find a colleague or friend with some node.js experience who is willing to contribute to this feature?


Update community page

I don't think so, but if you want it to be in alphabetical order, should it be by username or by first name?

if you want it to be in alphabetical order, should it be by username or by first name?

IMO probably username? That way you can just "sort lines" in your editor.

ping


Design additional required business-specific metrics

As a project developer, I want to define the set of business-specific metrics that should be collected in addition to the out-of-the-box metrics, so that these new custom metrics can be implemented in code

[ ] Design doc created that lists additional required metrics that are not instrumented by the application

Mentioned in #338


docs: code example on 'Fetching Before Navigation' with a better context

Hi Vue team 😄  I was reading the documentation at https://router.vuejs.org/guide/advanced/data-fetching.html#fetching-before-navigation, and I found the code example quite confusing. I'm coming from version 2 of Vue, and vm.setData() method confused me. I've asked myself if that is a new syntax to modify the data component, but it's not. Maybe I'm not the only person that thinks like this. So, I added more context with the method setData in the example 😃. Thanks

Thanks :D, done


Update header levels/spacing

Purpose
Update header levels and immediate spacing around them.
Why
As I read through the book I noticed that formatting was off in places, often when code ran up against headers or other blocks of content. I also noticed that some header levels appeared "off".
This PR is focused specifically on the header levels with follow-up PRs for other indirectly related formatting issues.
fixes #105

As noted on #105, I opened this PR (in its draft form) for review purposes. I plan to squash the commits and add a useful log message once the changes look good.

Note: not rushing in any way, just wanted to explicitly note that I'm waiting for feedback before moving further with this or related work. I looked back over my earlier notes and realized that I wasn't really clear about that.

Hey, sorry. Have been very busy. Give me some time.

Hey, sorry. Have been very busy.

Not a problem, I completely understand.

Hey man, do you want to be a collaborator on this project? I'll be happy to make you one.  I'll be happy to make you one. That way, you can commit to the repo without my "approval"

Certainly, I'm honored that you have made this offer. What do you propose to be the scope of my involvement? I primarily want to make sure that I don't exceed them and cause you any difficulties.

You can do anything. Review the PR if you have time, change things etc. I don't have any issues.

I've sent you an invite. Not sure how you'll access it though. and good luck!!

I'm logging off, have a good day.

I've sent you an invite. Not sure how you'll access it though. and good luck!!

Accepted, thanks!

You can do anything. Review the PR if you have time, change things etc. I don't have any issues.

Acknowledged, I'll do my best to keep the changes focused in an effort to make them easier to review later (if needed). Do you wish to be mentioned for PRs that I submit/merge?
Are you open to the idea of creating a development (or testing or some other similarly named) branch and then setting up Leanpub to accept GitHub push requests in order to generate Preview builds for the new branch?
I gave it a try on my free account and it worked well for proofing changes.

You can take a call about everything. If you have time then feel free and review PRs sent by others. I have moved away from Go so won't be aware of the new developments in the language.
 You can take your well thought out and positive  decisions without asking me. I'm reachable via email if you really need me. But I don't think you will need me though.

@thewhitetulip
Acknowledged and thanks for clarifying. Thanks also for the open invitation to reach out by direct email when I need to. I'll try to keep those to a minimum, but I appreciate the open door.
I have limited time and limited skill with Go (very much a newbie at this point), but I will do what I can to help.
Are you open to periodically regenerating new copies of the book via leanpub (and anywhere else you're publishing it)? If so, would you find it helpful to be pinged by direct email, by opening a new issue and assigning it directly to you?
To make things easier for us both, I'll probably keep regenerating new draft copies via my free leanpub account; only after a large batch is ready will I request a new official copy of the book be regenerated (again, assuming you're open to receiving periodic requests to refresh the book).

You can send me an email anytime. I don't mind. I'll update leanpub copy every week, that makes sense right?

Thanks for agreeing to receive emails.
Re leanpub, maybe not weekly, but monthly or by request?
I can open an issue and assign to you or send an email when enough changes are ready for publishing.

Sure. I don't mind that.

Generating a test copy based on this rebased branch. Will check for obvious issues before merging in the next day or so.

The only bits I'm not 100% sure about are the intended Table of Contents entries: what is intended to be top-level headings and which sub-heading.
I've attached a draft PDF copy for quick review (just the ToC entries).
If you don't have the time I can go with my initial impression and make whatever fixes are needed later.
antitextbookgo-atc0005-unofficialfork-preview.pdf
There are still other changes to make regarding formatting, but I'd like to include those in separate PRs to keep the changes distinct and (hopefully) easier to follow.

Hey, pls go ahead and make changes. I'll fix issues later :)

Hey, pls go ahead and make changes. I'll fix issues later :)

Fair enough. It was mainly the intended section order that I was considering a blocker of sorts, but if you see that I've set the headers wrong I guess open an issue? :)
I'll review this in a bit and get it merged.

@thewhitetulip Merged. More to come soon.


Create the build in an async manner to improve response time to webhooks

Hi,
I will give the context of this PR:
We have been working on a configuration plugin to handle our monorepo and the solution we came up with does the following steps:

clones the repo based on the build event in the same way https://github.com/drone/drone-git does it
looks for diff files affected by the current build
for affected each files it traverses the repo upward until it finds a drone config file
parses these drone config files and passes them to a template engine to compute the root drone file of the repository and send back the final config

Leveraging the multi-pipeline feature we have been able to come up with a solution which handles each microservice individually, erasing the drawbacks of monorepos in classic CI environments.
A root drone file using this can look like the following:
kind: pipeline
type: docker
name: "lint"

steps:
- name: lint
  image: golang:1.12
  commands:
  - lint

{{ if .Pipelines }}
{{ .Pipelines | toYaml }}
---
kind: pipeline
type: docker
name: "deploy"

steps:
- name: deploy
  image: debian
  commands:
  - deploy

depends_on:
{{ .PipelinesName | toYaml }}
{{- end }}

What we have done works great and we are planning to make it available to the community.
Yet there is one problem, our monorepo is pretty big and even though we created a cache mechanism using a mirror repo as reference, it still takes between 5~8 secs to fetch the repository in the configuration plugin and it leads to timeouts in the Github webhooks as the timeout is set at 10sec.
Following the good practices advised by github here https://developer.github.com/v3/guides/best-practices-for-integrators/, we've decided to come up with this PR which makes the handling of a webhook more asynchronous.
With this PR, the triggerer starts a goroutine to do most of the heavy lifting to create the build, if an error occurs, it creates the build with an error message.
Thanks for the feedbacks

 Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.You have signed the CLA already but the status is still pending? Let us recheck it.

First, thanks for the pull request 🙂
One concern I have is that always returning a build we give the impression a build was created, which is not always going to be the case. I see this causing confusion and resulting in support burden. For example, if the trigger condition is not satisfied the build is ignored, but a build is still returned in the hook body.
From an implementation perspective we would be better off always returning an empty body, to avoid any confusion. This would simplify the pull request and would only require changing a few lines of code in the hook handler.
	go triggerer.Trigger(ctx, repo, hook)
	writeStatus(w, 200)

Before making this change we also need to understand whether or not anything useful is being sent back in the hook response on error, because we would be taking that away from users who may be using it to debug today.  My gut tells me nothing useful is being returned, but we should verify anyway.
Lastly I had hoped one day to return more details in the response, including reasons a build may have been skipped. This will no longer be an option if we process the build async.
The timeout errors in GitHub can be unsightly, however, they do not prevent the trigger routing from executing and scheduling a build.
I am not opposing this change, I just wanted to document all the different things we will need to consider when making changes.

Thanks for the quick response.
Calling the whole trigger async definitely works for our issue.
When writing the PR I was thinking that if we wanted the response to be useful we might as well just have the correct build number in the response, that should be enough to debug, at least it's enough to call the drone API build info endpoint, but I missed the build being skipped in which case the response sent is invalid. What we could do though is create the build with the status "skipped" and with a message about why it was skipped.
As for debugging from the webhooks response, we are doing it but only for issues with our configuration plugin because that's the only way although I think it's easier to debug from drone itself because not every contributor has access to the webhooks response but they do have access to their builds on the drone UI.

What we could do though is create the build with the status "skipped" and with a message about why it was skipped.

this is not something I would want to do. This would create a lot of noise in the system and would create large gaps in build numbers.

this is not something I would want to do. This would create a lot of noise in the system and would create large gaps in build numbers.

I agree.
Trying to find another solution 🤔

I think the optimal solution probably looks something like this:

run trigger async and return a 200OK with an empty body
store the full hook in a table that is periodically pruned so that it does not grow too big
store the build id, error or skip reason inside the same record as the hook
provide an option for the user to dump hooks received

not all systems provide access to webhook responses (such as Bitbucket) and it often requires admin access.  So hook responses were never a great way to debug.  Storing the data in the system and making it accessible via endpoint should make it way easier for users to debug.

I like the idea. I think we can still make the response from the webhook useful doing something simple. What about that?

Store the hook in a table right away and return 200OK with a payload like:

{
  "hook_id": 1,
  "link": "https://drone.com/api/hooks/1"
}

start a goroutine to process the build, alternatively, a worker could poll the hook table for unprocessed hooks and process them (this adds delivery guarantee)
update the hook entry along the way with metadata such as build id, error, skip reason etc.
provide a hooks resource in the drone api and a hooks tab for each repo in the drone UI to see hooks history
add a repo settings for hooks retention period and have a worker clearing hooks for every repo when hooks are older than the retention period

yes, we'll have to come up with a more formal rfc (we don't want to rush into this) but I feel pretty good about the ideas being discussed so far.

I like the idea to store the webhooks. It's always a pain to find the right webhook within github for debugging.
I also like listing the hooks in the ui, we could show attributes where you always got to toggle the hook view within github directly in the list, and we could even filter them.

I don't know what's the decision-making process but if we go ahead at some point, I'd be happy to work on it :)

Brad is the project owner, so he is the one that decides the final solution, but he asked us, the other maintainers or contributors, for our opinion to get to a decision.

This PR has been automatically closed due to inactivity.


Unconnected input should cause an error, yes?

One of my steps has an unconnected input, due to an extend_inputs command in the construct.py without an accompanying g.connect for the step that is supposed to supply the input. In the example below, sram.spi is the unconnected input and gen_sram is the step that is supposed to supply the input to the lvs step.
  lvs.extend_inputs( ['sram.spi'] )   # Exists in construct.py
  # g.connect_by_name( gen_sram, lvs) # Does NOT exist in construct.py

It seems like, somewhere along the line, mflowgen should flag this as an error, e.g.
  % make lvs
  Error: no connection for input "sram.spi"

Or maybe:
  % make lvs
  Error: File "inputs/sram.spi" not found

FYI This (below) is what I see when I do "make info" on the offending step; note the unconnected "sram.spi" input. So mflowgen knows that the input is not connected...it's just not doing anything about it...

  % make info-24

       + 7-tsmc16
       + adk
       |
       |            + 21-cadence-innovus-signoff
       |            + design-merged.gds
       |            |
       |            |                + 21-cadence-innovus-signoff
       |            |                + design.lvs.v
       |            |                |
       |            |                |             + 2-custom-lvs-rules
       |            |                |             + rules.svrf
       |            |                |             |
       |            |                |             |              + 8-glb_tile
       |            |                |             |              + glb_tile.lvs.v
       |            |                |             |              |
       V            V                V             V              V
    +---------------------------------------------------------------------------------+
    | adk | design_merged.gds | design.lvs.v | rules.svrf | glb_tile.lvs.v | sram.spi |
    +---------------------------------------------------------------------------------+
    |                                                                                |
    |                              24-mentor-calibre-lvs                              |
    |                                                                                |
    +---------------------------------------------------------------------------------+
    |     lvs.report     |     design.schematic.spi     |     design_merged.lvs.v     |
    +---------------------------------------------------------------------------------+

I don't think it should be an error, but there is a problem yes. It is primarily about the lack of support for expressing requirements in the node configuration. However, I also don't think we should just add a way to express required inputs.
There are actually several groups right now that are designing nodes with inputs and outputs left hanging. They are adding new optional functionality to a node (e.g., adding saif map to synthesis for RTL-driven power analysis later downstream). They want to use the node in one project with that new piece, and also in another project without it. They want to share and use the same node, so they simply overdesign it for both scenarios.
I am looking forward to node inheritance solving this problem, since you will be able to inherit/specialize nodes with no more custom packages ... and it means that node interfaces can be specialized as well (possibly looking more method-based rather than somehow knowing which set of inputs go together).

Update: As an example of the usefulness of this feature, I wrote my own script find-unmatched-inputs.sh and inserted it into the CI for our garnet global-buffer flow. It found the error that I knew about, but also revealed a couple more about which I had not previously known. In particular, it looks like the default mflowgen cadence_innovus_debug_calibre step requires an input lvs_results but the default mflowgen mentor_calibre_lvs step does not supply that as a default output.
% find-unmatched-inputs.sh 16-glb_top/.mflowgen/graph.dot

WARNING found unconnected output edge   mentor_calibre_lvs     / <lvs_report>
WARNING found unconnected output edge   synopsys_dc_lib2db     / <design_db>
WARNING found unconnected output edge   tsmc16                 / <adk_lvs2>

ERROR found unconnected input edge   cadence_innovus_debug_calibre / <lvs_results>
ERROR found unconnected input edge   cadence_innovus_genlib / <sram_tt_lib>
ERROR found unconnected input edge   mentor_calibre_lvs     / <sram_spi>


Improve Cart UI

Hey @Open-Source-Chandigarh
Checked out your website, it was demn sick, keep up the good work man!
I would like to update the Cart Section UI, as it seems pretty rough as compared to other UI elements of the Website!

Thnks for listening to my issue, If you found it useful in any way do lemme know and we can work out on it!
Best Regards,
Shera Bhai

Thank you ! and for sure @sherabhai send me ss here before pr.

@Varinder-Dhillon0
Just Check it Out!
If you like it and approve, will submit the PR!

Best Regards,
Shera Bhai

@sherabhai colors are off and not per theme change that and make layout more good.

hey @sherabhai change colors back to what they were however keep the changes you made to layout spacing.

@sherabhai  check my previous comment

@Varinder-Dhillon0
Is it perfect now?

yes @shera-bhai

Can i suggest some UI changes on this

@IrfanshaikH-7
Yeah sure, much appreciated bro!
It'll be good if I could get a reference too 😅
Just lemme know and will submit the PR soon!

How about something like this for the layout - product and its quantity one side and the amount and quantity-counter other side?

@Varinder-Dhillon0
Sorry for all the delay, was busy in a Hackathon!
Actually I'm not authenticating it, normally running the App.. that's why the Username is not shown!

yes @shera-bhai  the one mentioned by @IrfanshaikH-7 looks great and make checkout button's text white

@Varinder-Dhillon0
Hope you like it!

Best Regards,
Shera Bhai

this one looks good @shera-bhai make a pr


Issue-528: HandlerMethodArgumentResolver to resolve Repository instance based on {storageId}/{repositoryId} path variables

Fixes #528.
Created a resolver which:

Checks if exists a method parameter annotation RepositoryMapping with a parameter type Repository.
If there's no storageId nor repositoryId path variables, a MissingPathVariableException is thrown.
Validates the existence of an storage and a repository. Otherwise an ElementNotFoundException is thrown.
Validates if repository is in service. Otherwise a ServiceUnavailableException is thrown.

Tasks

[x] Modify all affected controller methods with path variables {storageId}/{repositoryId}, and replace the parameters with new annotation RepositoryMapping.

Acceptance Test

[x] Building the code with mvn clean install -Dintegration.tests still works.
[x] Running mvn spring-boot:run in the strongbox-web-core still starts up the application correctly.
[x] Building the code and running the strongbox-distribution from a zip or tar.gz still works.
[x] The tests in the strongbox-web-integration-tests still run properly.

@carlspring This is ready for review. Any suggestions are welcome.

@fuss86 , @sbespalov ,
Could you please review this pull request?

@ptirador thank you for your hard work, but it needs to wait for https://github.com/strongbox/strongbox/pull/1272

@ptirador ,
Could you please rebase? Thanks! :)
@fuss86 ,
Is it good to go after the rebase?

@sbespalov ,
Will this pull request be affected by #1293?

I forgot to mention that #1272 has been merged.

@ptirador ,
Could you please rebase? Thanks! :)
@fuss86 ,
Is it good to go after the rebase?

Rebase done.

Thanks, @ptirador :)

Thanks so much for your tips, @fuss86 and @sbespalov!
I've fixed almost everything that you said, except for two things:

This discussion about the need of casting the Repository class, which should be in a follow-up task. CC @carlspring

2.This discussion about receiving the Repository class from request atribute. I'm not very sure how to implement this, could you help me?
Thanks.

@fuss86: changes fixed!

@carlspring: if there's no more review requests, this would be ready.

@fuss86 / @sbespalov ,
Do you have other remarks, or should I proceed with merging it?

Thanks, @ptirador !


Milestone 0.5.0

PR for 0.5.0. Changes include the following:

Update minimum version to Python 3.9

As this is a major release, we won't be running the MCprep build tests, as it's expected to break

Support for extensions

[x] build_extension toggle for legacy addons (extensions are the default now)
[x] Alternate implementation of Blender's Manifest verification with lib_bpybuild_ext

This is due to issues with including GPL code into a BSD licensed project
Known parity issues, but we're basing this off of the Blender documentation directly. I've pushed a few PRs upstream to help improve the documentation where possible, but one can only go so far

[x] Support for building extensions and legacy addons	at the same time

[x] is_extension flag in BabContext

[x] Restrict extension installation to Blender 4.2+
[x] Write tests for extension building
[ ] override_extension setting to allow overriding the built-in extension action

Improve experience with chains of actions

[x] Allow defining required actions if an action needs a previous action to run

[ ] bab action-chain command to visualize the chain of actions and the actions they depend on
[ ] Create a system for actions to pass data to subsequent actions

Added test for extension building and building with legacy builds. Incredibly basic, but still a WIP

Considering this feature complete

And finally, it seems I'm successfully able to generate an extension of MCprep, although I need to manually remove the leading _ of _blender_manifest.toml, and then when installing manually it recognizes it but trying to later manually enable the addon I get the below - not sure if that's a new thing or not.
Exception in module register(): /Users/patrickcrawford/Library/Application Support/Blender/4.3/extensions/user_default/mcprep/__init__.py
Traceback (most recent call last):
  File "/Applications/Blender 4.3/blender.app/Contents/Resources/4.3/scripts/modules/addon_utils.py", line 488, in enable
    mod.register()
  File "/Users/patrickcrawford/Library/Application Support/Blender/4.3/extensions/user_default/mcprep/__init__.py", line 65, in register
    load_modules.register(bl_info)
                          ^^^^^^^
NameError: name 'bl_info' is not defined

Blender is weird with extensions made from legacy addon codebases: if you define a blender_manifest.toml file, Blender deletes the whatever bl_info variable has been defined. However, since it's just an action called extension that can be overridden (we do have an override for MCprep, although that will need to be updated to take advantage of lib_bpybuild_ext), I think it should be safe to merge this.


Doesn't work with 1Password CLI v2.x

Describe the bug
1Password released a v2.x of their CLI, and introduced breaking changes in the commands, for instance now the commands are something like:
op item list --categories login --tags SSHKeys

instead of what currently ssh-manager is expecting:
op list  items --categories login --tags SSHKeys

Below the error when trying to run ssh-manager list
❯ ssh-manager list --provider op
Error: 'op list': Execution failed: exit status 1: [ERROR] 2022/05/27 17:08:39 unknown command "list" for "op"
Usage:  op [command] [flags]

Management Commands:
  account     Manage your locally configured 1Password accounts
  connect     Manage Connect instances and Connect tokens in your 1Password account
  document    Perform CRUD operations on Document items in your vaults
  events-api  Manage Events API integrations in your 1Password account
  group       Perform CRUD operations on the groups of users in your 1Password account
  item        Perform CRUD operations on the 1Password items in your vaults
  user        Manage users within this 1Password account
  vault       Manage permissions and perform CRUD operations on your 1Password vaults

Commands:
  completion  Generate shell completion information
  inject      Inject secrets into a config file
  read        Read a secret using the secrets reference syntax
  run         Pass secrets as environment variables to a process
  signin      Sign in to a 1Password account
  signout     Sign out of a 1Password account
  update      Check for and download updates.

Global Flags:
      --account account    Select the account to execute the command by account shorthand, sign-in address, account ID, or user ID. For a list
                           of available accounts, run 'op account list'. Can be set as the OP_ACCOUNT environment variable.
      --cache              Store and use cached information.
      --config directory   Use this configuration directory.
      --debug              Output debug logs. Can also be set using $OP_DEBUG environment variable.
      --encoding type      Use this character encoding type. Default: UTF-8. Supported: SHIFT_JIS, gbk.
      --format string      Use this output format. Can be 'human-readable' or 'json'. Can be set as the OP_FORMAT environment variable.
                           (default "human-readable")
  -h, --help               Get help for op.
      --iso-timestamps     Format timestamps according to ISO 8601 / RFC 3339. Can be set as the OP_ISO_TIMESTAMPS environment variable.
      --no-color           Print output without color.
      --session token      Authenticate with this session token. 1Password CLI outputs session tokens for successful 'op signin' commands when
                           biometric unlock is disabled.

Run 'op [command] --help' for more information on the command.

To Reproduce
Steps to reproduce the behavior:

Install the new 1Password CLI
Try to list/get a SSH Key using ssh-manager

Expected behavior
Get/list the SSH Key items stored in 1Password
Environment:

CLI Version (retrieve with ssh-manager version): INFO[27-05-2022 17:11:12] ssh-manager v1.0.0
Operating System/Architecture: macOS Monterey v12.4/ARM64

We can support v1.x and v2.x together but it would require some work. Personally, I still use v1.x. I cannot assume everyone uses the new version.

Thanks for the quick response.
I was thinking that probably an approach will be to to have a op2 provider, it seems most of the code will be the same just need to adjust the CLI params order.
I can try to prepare a PR if you are interested

Feel free to create a PR for it, I would definitely contribute.


bastion_launch_configuration_name is listed as optional, but plan fails if not provided

Error: module.vpc-bastion.aws_launch_configuration.bastion_launch_configuration: expected length of name_prefix to be in the range (1 - 229), got

Same issue here.


Add information_schema.index_statistics metric

I have a suspicion that this one
https://github.com/shatteredsilicon/ssm-submodules/issues/105
will need
engine_innodb_status = 1
in the conf file.
Is it worth defaulting this to 1 now?

Yeah, you are right, we need engine_innodb_status = 1 for that, but I don't think it's necessary to set it now, we will need more code patch in this repo for that feature, we can set it by then.

Fair enough.


fix log truncate_suffix bug

truncate_suffix order must be from back to front, otherwise it can break log matching property of raft.
For example, considering five servers.
(server #: terms of logs)
server 1: ...9 10 10 10
server 2: ...9 11 11
server 3: ...9
server 4: ...9
server 5: ...9 10 10 10
Now server 2 is a leader with term 11 and send AppendEntries rpc to server 1. If server 1 crash while truncating from front to back, log can be 9 (empty) (empty) 10.
And then server 2 crash. server 5 get server 3 and 4's vote and become a leader with term 12.
Afterward server 1 come back to life. Server 5 send AppendEntries rpc to 1 and find the last matching log and add a log with term 12.
server 1: ...9 (empty) (empty) 10 12
server 2: ...9 11 11(crashed)
server 3: ...9 10 10 10 12
server 4: ...9 10 10 10 12
server 5: ...9 10 10 10 12
Server 5 think the first log with term 12 can be committed.

The truncate suffix order in original code is that the unique last-need-truncated segment first, and then unlink latter segments from back to front.
Although the unit is a segment not a log, it has the same problem.
In original code, previous example may lead to server 1 can't revive because of checking validity of segments(e.g. the log sequence number is not continuous).
However it's not enough just to check index from file name. Crash may happen before renaming the corresponding file. In this case, server 1 revive but may crash on any call to get its empty log Entry(_offset_and_term vector out of range in Segment::get_meta).
l have added code in Segment::load to repair last index in file name and moved check_segments after load_segments.

Rename failure in Segment::truncate should return error, otherwise next time rename(add .tmp) in unlink or truncate will fail because _last_index in memory is not consistent with its file name.

In SegmentLogStorage::pop_segments_from_back, l think it make no sense to set _first_log_index if all segments need to be deleted because the meaningful interval of last_index_kept should be [_first_log_index -1, _last_log_index](last_index_kept = _first_log_index - 1, so set _first_log_index = last_index_kept + 1 is no use). To say the least, if it does make sense to set _first_log_index, save_meta should called to save right _first_log_index to disk. This confused me, so l didn't change it.

l am sorry for not adding unit test for my code because unit test is hard to check above problems.

@chenzhangyi @ipconfigme @Edward-xk
It's a serious problem in my opinion. Please have a look.

Good issue. I think the data consistency problem is caused by a full segment lost it's data. Does I understand correctly?
We have a fix for the similar problems in the develop version of braft inside Baidu, and I will sychronize push it to github.

This is not very right. The key of this problem is that the order of truncating suffix is not from back to front. A hole may exist in log consequently. Another problem is that crash may happen before renaming the full segment file name. So it is necessary to recover file name after restarting server.
OK! l am glad to see the repaired code. But it doesn't seem to be updated yet.
So should l close this PR?

This is not very right. The key of this problem is that the order of truncating suffix is not from back to front. A hole may exist in log consequently. Another problem is that crash may happen before renaming the full segment file name. So it is necessary to recover file name after restarting server.
OK! l am glad to see the repaired code. But it doesn't seem to be updated yet.
So should l close this PR?

Sorry, I'm packing the patchs, including this one and some other bugfix and features. I will pull them to github this week.
Ok, I fully understand your meaning, you are right, your fix is crash safe to the problem.

I have two extra opinions for the problem:

We can do rename before truncate when Segment::truncate() truncate a full segment. This can keep the segment in consistency.
At load stage, i think we can just core if we found log consistency problem.

I have two extra opinions for the problem:

We can do rename before truncate when Segment::truncate() truncate on a full segment. This can keep the segment in consistency.
At load stage, i think we can just core if we found any log consistency problem. It's no necessary rename log from full segment to open segment again, espacially after we fix Segment::truncate().

Yes you are right！But it may still need to add some check and truncate unneeded log at load stage.


Remove inaccurate references to "garbage", fix default for Orleans 7.x+

Fixes #39451
Also, use the term "activation collection" consistently and drop the term "garbage" to hopefully reduce conflation with GC.
@IEvangelist is there a way to change the URL to activation-collection instead of activation-garbage-collection and redirect from the latter to the former?

Internal previews

📄 File
🔗 Preview link

docs/orleans/host/configuration-guide/activation-collection.md
Activation collection

Hey @ReubenBond - yeah, you can rename the file, and update all references to the file, i.e.; any TOC.yml and index.yml/md files, or other .md files that link to it. Then you'd add a redirect entry in the orleans redirection file at the root /docs dir of the repo. Happy to help with that, does it make sense?

@IEvangelist ptal


Clippy failing on master

Describe the bug
CI clippy checks are failing
https://github.com/apache/arrow-datafusion/actions/runs/3386593123/jobs/5626537564
   Compiling datafusion-proto v13.0.0 (/__w/arrow-datafusion/arrow-datafusion/datafusion/proto)
error: deref which would be done by auto-deref
  --> datafusion/proto/build.rs:51:17
   |
51 |         .expect(&*format!("Cannot read {:?}", &descriptor_path));
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `&format!("Cannot read {:?}", &descriptor_path)`
   |
   = note: `-D clippy::explicit-auto-deref` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref

error: deref which would be done by auto-deref
  --> datafusion/proto/build.rs:55:17
   |
55 |           .expect(&*format!(
   |  _________________^
56 | |             "Cannot register descriptors {:?}",
57 | |             &descriptor_set
58 | |         ))
   | |_________^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref
help: try this
   |
55 ~         .expect(&format!(
56 +             "Cannot register descriptors {:?}",
57 +             &descriptor_set
58 ~         ))
   |

To Reproduce
run rustup update and then cargo clippy
Expected behavior
A clear and concise description of what you expected to happen.
Additional context
Rust 1.65 was released https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html
https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#rust-165

Working on this

to fix https://github.com/apache/arrow-datafusion/pull/4101


Help

need to update again ?

every patch i guess

I think the original creator abandoned the project. We rely on other people to find the signatures.

I think the original creator abandoned the project. We rely on other people to find the signatures.

the project is not abandoned. it got updated yesterday

also check my reply in #76


Create a User-Based Recommendation Model

story#15
As a customer, I want to see a list of recommended products based on my purchasing habits so that I can discover products that I am likely to buy.
### Details and Assumptions:
Recommendations are not limited to specific products and are generated based on the user’s purchase history. The recommendation model considers the frequency and type of purchases made by the user.
### Acceptance Criteria:
Displayed items are based on the user's historical purchase data. Displayed items are relevant and personalized to the user's buying habits.


Issues with Cilium in eBPF replacement mode on Rocky 9.1

Is there an existing issue for this?

[X] I have searched the existing issues

What happened?
When trying to run Cilium in eBPF replacement mode on Rocky 9.1, I'm running into several issues:

The agent fails to start, logging it could not find the kernel config file. I can work around this by manually adjusting the agent daemonset to mount the /boot directory again, as was removed in 1.13.x.
Even if the /boot mount workaround is implemented, I still have to temporarily delete the cert-manager webhooks, otherwise the kube API server is unable to process the requests from the cilium operator to add the custom resourcs. I also needed to manually restart the kube API server container after removing the webhooks to get this to go through.

Running Cilium in regular kube-proxy mode has no issues at all.
Any idea what could be causing this?
Cilium Version
Client: 1.15.3 22dfbc58 2024-03-26T11:45:10+01:00 go version go1.21.8 linux/amd64
Daemon: 1.15.3 22dfbc58 2024-03-26T11:45:10+01:00 go version go1.21.8 linux/amd64

Kernel Version
Linux maas-pool-10.metal.dreamworx.nl 5.14.0-362.24.1.el9_3.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Apr 4 22:31:43 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Kubernetes Version
Client Version: v1.28.5
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.5

Regression
Unknown
Sysdump
cilium-sysdump-20240510-101723.zip
Relevant log output
No response
Anything else?
No response
Cilium Users Document

[X] Are you a user of Cilium? Please add yourself to the Users doc

Code of Conduct

[X] I agree to follow this project's Code of Conduct

Solved it. It turned out the /etc/resolv.conf contained a DNS server on the first line that was a leftover of the image-build process. This invalid DNS server entry was causing the actual issue with the kube API server, as the DNS lookup delay triggered the timeout for the cert-manager webhook.
Clearing the invalid entry from /etc/resolv.conf fixed all issues.