Support LoRA hotswapping and multiple LoRAs at a time

This is a PR to add support for loading and changing LoRA adapters at runtime as introduced into llama.cpp in https://github.com/ggerganov/llama.cpp/pull/8332 by @ngxson. Adding this support should allow things like loading a base model, then swapping adapters in and out to support different features and behaviours. This could be really useful in smaller environments where we might use smaller models but want to support a variety of capabilities. (This appears to be the approach taken by some commercial mobile device makers.)
The list of changes from upstream in https://github.com/ggerganov/llama.cpp/pull/8332 are:

Refactor lora API
Allow hot-swapping lora
Added struct llama_lora_adapter to keep track of loaded lora

I have made some llama-cpp-python changes to enable this support:

Updated C wrappers
Added _internals.LlamaLoraAdapter to wrap llama.cpp's llama_lora_adapter
Modified wrapper lifecycle to free llama_lora_adapter correctly
Added high level API in Llama wrapper - now supports a dict of LoRA adapters to reflect llama.cpp's support for multiple LoRAs; also has method for changing LoRA scales
Updated cache to have LoRA adapter weights in cache keys, because different active LoRAs will have different cache state
Updated server to support hot-swapping LoRAs when a base model is shared

I have an example of usage through the API and via the server here: https://gist.github.com/richdougherty/dd4961a72fafbff5216b4bc9f48b1147#file-lora-md
Example API usage:
>>> import llama_cpp
>>> llm = llama_cpp.Llama("<model>") # Can also add LoRAs in dict here
>>> llm.lora_adapters
>>> llm.create_completion(seed=12345, temperature=0, max_tokens=256, prompt=".....", stop=["\n"])
>>> llm.set_lora_adapter_scale('./adapters/lora_tldr_headline_gen.gguf', 1.0)
>>> llm.lora_adapters
{'./adapters/lora_tldr_headline_gen.gguf': 1.0}
>>> llm.create_completion(seed=12345, temperature=0, max_tokens=256, prompt=".....", stop=["\n"])
>>> llm.set_lora_adapter_scale('./adapters/lora_tldr_headline_gen.gguf', 0.0)
>>> llm.lora_adapters
{'./adapters/lora_tldr_headline_gen.gguf': 0.0}
>>> llm.set_lora_adapter_scale('./adapters/lora_tldr_content_gen.gguf', 1.0)
>>> llm.lora_adapters
{'./adapters/lora_tldr_headline_gen.gguf': 0.0, './adapters/lora_tldr_content_gen.gguf': 1.0}
>>> llm.create_completion(seed=12345, temperature=0, max_tokens=256, prompt=".....", stop=["\n"])

Still working on this. Just added support to the OpenAI-compatible server for hot-swapping LoRAs via model aliases. This allows fast serving of different LoRA adapters that extend the same base model with minimal switching overhead.
{
    "host": "<IP_ADDRESS>",
    "port": 8080,
    "models": [
        {
          "model_alias": "mistral",
          "model": "/home/rich/.cache/huggingface/hub/models--TheBloke--Mistral-7B-v0.1-GGUF/snapshots/d4ae605152c8de0d6570cf624c083fa57dd0d551/mistral-7b-v0.1.Q4_K_S.gguf",
          "verbose": true
        },
        {
          "model_alias": "mistral-magicoder",
          "model": "/home/rich/.cache/huggingface/hub/models--TheBloke--Mistral-7B-v0.1-GGUF/snapshots/d4ae605152c8de0d6570cf624c083fa57dd0d551/mistral-7b-v0.1.Q4_K_S.gguf",
          "lora_adapters": {
            "/home/rich/dev/local-multi-lora/magicoder-lora-mistral-7b-v0.1.gguf": 1.0
          },
          "verbose": true
        },
        {
          "model_alias": "mistral-conllpp",
          "model": "/home/rich/.cache/huggingface/hub/models--TheBloke--Mistral-7B-v0.1-GGUF/snapshots/d4ae605152c8de0d6570cf624c083fa57dd0d551/mistral-7b-v0.1.Q4_K_S.gguf",
          "lora_adapters": {
            "/home/rich/dev/local-multi-lora/conllpp-lora-mistral-7b-v0.1.gguf": 1.0
          },
          "verbose": true
        }
    ]
}

Then calling the OpenAI compatible API with "model": "mistral, "model": "mistral-magicoder, "model": "mistral-conllpp" will result in a hot-swap, e.g
Hot-swapping model, setting existing LoRA adapter scales to 0.0.
Hot-swapping model, setting LoRA adapter scales for mistral-conllpp.
llama_lora_adapter_init_internal: loading lora adapter from '/home/rich/dev/local-multi-lora/conllpp-lora-mistral-7b-v0.1.gguf' ...
llama_lora_adapter_init_internal: CPU_Mapped LoRA buffer size =    13.00 MiB
llama_lora_adapter_init_internal: loaded 128 tensors from lora file

The code is pretty much done and working. I plan to tidy it up a little this weekend, ready for review and (hopefully) merge.

Thanks Rich. Let me know when I can try it out.

The code is ready for review now, thanks for your patience!
@hrsmanian , if you want to try it out before it is merged, a guide for usage is here: https://gist.github.com/richdougherty/dd4961a72fafbff5216b4bc9f48b1147

However, when I run it on 1000's of converasations, i see a constant increase in gpu memory. Could there be a memory leak? Or should we completely disable Lora adapters

That sounds like a memory leak for sure. Can you give me a bit more information about how you're running it? Are you loading (and unloading) LoRA adapters? Are you using the http server or the API? Also any info on how you're measuring memory usage, how fast it is growing, etc might be useful. Thanks!

@richdougherty , I am running offline inference in a loop loading one conversation at a time
And in another window, I run nvidia-smi to see the gpu memory usage. It increases by roughly 4Mb for each inference.
I load the model and set the lora as below.
import llama_cpp
import json
import time
llm = llama_cpp.Llama("gguf_models/Llama-3.2-3B-Instruct-f16.gguf", n_gpu_layers=-1, verbose=False, n_ctx=6000)
#loading both the adapters
llm.set_lora_adapter_scale('gguf_models/lora_3b_exp42_f16.gguf', 0.0)
llm.set_lora_adapter_scale('gguf_models/lora_3b_exp43_f16.gguf', 0.0)
infile = "val_English.jsonl"
fp = open (infile, "r")
time1 = 0.0
time2 = 0.0
count = 0
for line in fp:
json_data = json.loads(line.strip())
dialogue = json_data['dialogue']
model_prompt = f"Summarize the text"

s1 = time.time()
############## activate 1st adapter and disable 2nd adapter
llm.set_lora_adapter_scale('gguf_models/lora_3b_exp42_f16.gguf', 1.0)
llm.set_lora_adapter_scale('gguf_models/lora_3b_exp43_f16.gguf', 0.0)
print(f"LoRA State1: {llm.lora_adapters}")

prompt_1 = f"""<|start_header_id|>system<|end_header_id|>
You are a helpful AI assistant for conversation summarization<|eot_id|><|start_header_id|>user<|end_header_id|>
{model_prompt}: {dialogue}<|eot_id|><|start_header_id|>assistant<|end_header_id|>
"""
output = llm.create_completion(seed=12345, temperature=0.01, top_p=0.99, top_k=250, max_tokens=256, prompt=prompt_1, stop=['<|eot_id|>'])
time1 += time.time() -  s1
print_out1 = f"""MODEL OUTPUT:\n\n {output['choices'][0]['text']}
Usage:
Input Tokens: {output['usage']['prompt_tokens']}
Output Tokens: {output['usage']['completion_tokens']}
Total Tokens: {output['usage']['total_tokens']}

"""
print(print_out1)

Hi, anymore information needed on this? Kindly let me know

Hi @hrsmanian, apologies for the time to get back. Based on your explanation - seeing GPU memory usage increasing - it sounds like a leak in the llama.cpp allocated GPU memory. This could indicate either a bug in llama.cpp's LoRA adapter code or - more likely! - a bug in the bindings that I wrote.
A bug in the llama-cpp-python bindings in this PR would be something like incorrectly using the llama.cpp API and therefore causing those extra GPU allocations for LoRA adapters and perhaps forgetting to deallocate somehow.
Unfortunately, I only have a CPU for inference, but I believe I should be able to spot an incorrect usage of the llama.cpp LoRA API by seeing RAM usage increasing for the Python process. This is because llama.cpp will use the process RAM to store the models and adapters when using CPU inference. So because I'm using system RAM then I think that any mistakes with allocating or deallocating LoRA adapters should show up in the Python RAM usage directly as an increase in virtual memory usage.
Note: a Python object memory leak in the bindings might not show up, since the Python heap might not visibly grow with each object due to its garbage collected nature. But I think that looking at Python process RAM usage should be good enough to show the kind of leak that you're talking about in llama.cpp allocated memory. The memory allocated by llama.cpp won't be using the Python garbage collected heap for its memory allocation, therefore it should be allocating memory directly which will be visible in the process memory used.
Test script
I've written a little script to test this. I'm using psutil to check the Python process RAM usage after each operation. This works for me for testing a leak when using CPU for inference.
I do not see a leak using this to test. Certainly nothing on the order of 4MB for each inference. Would you mind checking the script on your machine as well? I can also test your script if you want to link to your models / adapters and dataset you use to test, but I understand that these might be private.
You can try it using psutil to view RAM usage. To help with the GPU memory leak debugging perhaps you could edit the script so that it reports GPU usage. I saw there are a couple of libraries that can help with this (not tested by me). These are https://github.com/pmav99/nvsmi or https://pypi.org/project/nvidia-ml-py/ . You could patch the log_mem function to report GPU memory usage. That could give a useful log showing any leaks in GPU memory.
For my tests I am using the model and adapters described in the guide I wrote before: https://gist.github.com/richdougherty/dd4961a72fafbff5216b4bc9f48b1147 . This test only tests very short prompts and completions. I tried a slightly larger prompt and completion further down in this comment, but perhaps you can test using your dataset as well.
export MODEL_GGUF=$(huggingface-cli download TheBloke/Mistral-7B-v0.1-GGUF mistral-7b-v0.1.Q4_K_S.gguf)
export ADAPTER1_GGUF=./adapters/lora_tldr_headline_gen.gguf
export ADAPTER2_GGUF=./adapters/lora_tldr_content_gen.gguf

pip install psutil

python memtest.py 2>&1

memtest.py
import os

model_gguf = os.environ['MODEL_GGUF']
adapter1_gguf = os.environ['ADAPTER1_GGUF']
adapter2_gguf = os.environ['ADAPTER2_GGUF']

import psutil

process = psutil.Process()

prev_vms = 0
prev_rss = 0
def log_mem(msg):
  global prev_rss, prev_vms
  pmem = process.memory_info()
  vms = pmem.vms
  rss = pmem.rss
  delta_vms = vms - prev_vms
  delta_rss = rss - prev_rss

  print(f'====== {msg:<40} {vms:>16,} ({delta_vms:>+16,}) {rss:>16,} ({delta_rss:>+16,}) ======')

  prev_vms = vms
  prev_rss = rss

log_mem('initial')

import llama_cpp

log_mem('imported llama_cpp')

llm = llama_cpp.Llama(model_gguf)

log_mem('loaded model')

i = 0
for i in range(0, 100):

  # Create a pattern of enablement so we can see all patterns of enabled/disabled
  # as well has having sequences where no changes happen.
  desired_adapter1_scale = i // 2 % 2 * 1.0 # Enable 2 out of every 4 times
  desired_adapter2_scale = i // 4 % 2 * 1.0 # Enable 4 out of every 8 times

  # Check current state - note that we treat the initial state when they are not
  # loaded as 0.0 to ensure we have a couple of tests without them loaded
  lora_adapters = llm.lora_adapters or {}
  current_adapter1_scale = lora_adapters.get(adapter1_gguf, 0.0)
  current_adapter2_scale = lora_adapters.get(adapter2_gguf, 0.0)

  if current_adapter1_scale != desired_adapter1_scale:
    llm.set_lora_adapter_scale(adapter1_gguf, desired_adapter1_scale)
    log_mem(f'after set adapter 1 scale {desired_adapter1_scale}')
  if current_adapter2_scale != desired_adapter2_scale:
    llm.set_lora_adapter_scale(adapter2_gguf, desired_adapter2_scale)
    log_mem(f'after set adapter 2 scale {desired_adapter2_scale}')

  llm.create_completion(seed=12345, temperature=0, max_tokens=16, prompt=str(i))
  log_mem(f'after completion "{i}"')

When I run this I see initial allocations in virtual memory (first column) but it stays stable after the adapters have been loaded. The RAM usages stays the same after various loads and unloads.
python memtest.py 2>/dev/null

====== initial                                        36,880,384 (     +36,880,384)       19,529,728 (     +19,529,728) ======
====== imported llama_cpp                            314,400,768 (    +277,520,384)       42,971,136 (     +23,441,408) ======
====== loaded model                                4,740,259,840 (  +4,425,859,072)    4,262,637,568 (  +4,219,666,432) ======
====== after completion "0"                        4,774,264,832 (     +34,004,992)    4,263,817,216 (      +1,179,648) ======
====== after completion "1"                        4,774,264,832 (              +0)    4,263,817,216 (              +0) ======
====== after set adapter 1 scale 1.0               4,789,526,528 (     +15,261,696)    4,279,021,568 (     +15,204,352) ======
====== after completion "2"                        4,789,526,528 (              +0)    4,279,021,568 (              +0) ======
====== after completion "3"                        4,789,526,528 (              +0)    4,279,021,568 (              +0) ======
====== after set adapter 1 scale 0.0               4,789,526,528 (              +0)    4,279,021,568 (              +0) ======
====== after set adapter 2 scale 1.0               4,803,383,296 (     +13,856,768)    4,292,915,200 (     +13,893,632) ======
====== after completion "4"                        4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
====== after completion "5"                        4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
====== after set adapter 1 scale 1.0               4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
====== after completion "6"                        4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
====== after completion "7"                        4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
====== after set adapter 1 scale 0.0               4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
====== after set adapter 2 scale 0.0               4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
====== after completion "8"                        4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
...

Small RSS changes
Note that I am seeing a small (128k) occasional increase in resident memory usage (last column), which could be a different kind of leak, for example Python VM operations such as GC not reclaiming everything straight away. I don't think this is your memory leak though because I would expect llama.cpp allocated memory to be reflected in an increase in the virtual memory (first column), not just an increase in resident memory. Nonetheless, worth keeping an eye on it.
...
====== after set adapter 1 scale 1.0               4,803,383,296 (              +0)    4,292,915,200 (              +0) ======
====== after completion "10"                       4,803,383,296 (              +0)    4,293,046,272 (        +131,072) ======
====== after completion "11"                       4,803,383,296 (              +0)    4,293,046,272 (              +0) ======
...
====== after set adapter 2 scale 0.0               4,803,383,296 (              +0)    4,293,046,272 (              +0) ======
====== after completion "72"                       4,803,383,296 (              +0)    4,293,177,344 (        +131,072) ======
====== after completion "73"                       4,803,383,296 (              +0)    4,293,177,344 (              +0) ======
...
====== after set adapter 2 scale 1.0               4,803,383,296 (              +0)    4,293,177,344 (              +0) ======
====== after completion "100"                      4,803,383,296 (              +0)    4,293,308,416 (        +131,072) ======
====== after completion "101"                      4,803,383,296 (              +0)    4,293,308,416 (              +0) ======
...
====== after completion "253"                      4,803,383,296 (              +0)    4,293,308,416 (              +0) ======
====== after set adapter 1 scale 1.0               4,803,383,296 (              +0)    4,293,308,416 (              +0) ======
...

Testing larger prompt and completion size
The previous test only tested completions for short numbers as prompts with very small max token size. A slightly larger test might show a leak.
I patched the create_completion call to generate something a bit larger. This used more memory but didn't seem to leak either.
  llm.create_completion(seed=12345, temperature=0, max_tokens=256, prompt=str(i) + ' the quick brown fox jumped over the lazy dog who knows what will come next with a longer prompt')

====== initial                                        36,884,480 (     +36,884,480)       19,660,800 (     +19,660,800) ======
====== imported llama_cpp                            314,400,768 (    +277,516,288)       42,971,136 (     +23,310,336) ======
====== loaded model                                4,740,255,744 (  +4,425,854,976)    4,262,821,888 (  +4,219,850,752) ======
====== after completion "0"                        4,774,723,584 (     +34,467,840)    4,267,278,336 (      +4,456,448) ======
====== after completion "1"                        4,774,723,584 (              +0)    4,267,278,336 (              +0) ======
====== after set adapter 1 scale 1.0               4,789,907,456 (     +15,183,872)    4,282,482,688 (     +15,204,352) ======
====== after completion "2"                        4,789,907,456 (              +0)    4,282,482,688 (              +0) ======
====== after completion "3"                        4,789,907,456 (              +0)    4,282,482,688 (              +0) ======
====== after set adapter 1 scale 0.0               4,789,907,456 (              +0)    4,282,482,688 (              +0) ======
====== after set adapter 2 scale 1.0               4,803,760,128 (     +13,852,672)    4,296,376,320 (     +13,893,632) ======
====== after completion "4"                        4,803,760,128 (              +0)    4,296,507,392 (        +131,072) ======
====== after completion "5"                        4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after set adapter 1 scale 1.0               4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after completion "6"                        4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after completion "7"                        4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after set adapter 1 scale 0.0               4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after set adapter 2 scale 0.0               4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after completion "8"                        4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after completion "9"                        4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after set adapter 1 scale 1.0               4,803,760,128 (              +0)    4,296,507,392 (              +0) ======
====== after completion "10"                       4,803,760,128 (              +0)    4,296,769,536 (        +262,144) ======
====== after completion "11"                       4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after set adapter 1 scale 0.0               4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after set adapter 2 scale 1.0               4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after completion "12"                       4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after completion "13"                       4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after set adapter 1 scale 1.0               4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after completion "14"                       4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after completion "15"                       4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after set adapter 1 scale 0.0               4,803,760,128 (              +0)    4,296,769,536 (              +0) ======
====== after set adapter 2 scale 0.0               4,803,760,128 (              +0)    4,296,769,536 (              +0) ======

Thanks Rich. I am still seeing a memory leak in GPU. Will try a previous build without your changes and keep you posted

Thanks for checking. To confirm, you ran the script I posted above?
If you are still seeing the leak my theory is that there's a leak in the llama.cpp CUDA implementation, which is why you're seeing the leak but I'm not seeing it with the CPU backend.
Currently I'm not thinking the leak is in the Python bindings, because if it was then I think we should see the leak for both backends.
This is just my theory though. I would definitely want more info to confirm - eg test different backends, try to replicate in llama.cpp directly.
If you're able then, running the script above would be good. If you don't have a chance then I should be able to use a cloud server with a GPU to test. (I am investigating how to do that.)
Thanks a lot for your interest and for testing!

Have a decent repro now
I added the nvidia-smi output into your script. also, the model being used is the model i trained. Below is the output snapshot when no adapter is used. GPU memory remains constant. All Good.
====== after completion "1"                       49,240,797,184 (        +532,480)    1,255,649,280 (        +659,456) ======
GPU Memory Used:  [6729]
====== after completion "2"                       49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "3"                       49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "4"                       49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "5"                       49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "6"                       49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "7"                       49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "8"                       49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "9"                       49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "10"                      49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "11"                      49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "12"                      49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "13"                      49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "14"                      49,240,797,184 (              +0)    1,255,649,280 (              +0) ======
GPU Memory Used:  [6729]
====== after completion "15"
Now below is the memory log when adapter is set. GPU memory increasing constantly
====== after completion "1"                       49,240,805,376 (        +532,480)    1,255,985,152 (        +598,016) ======
GPU Memory Used:  [6729]
====== after completion "2"                       49,362,423,808 (    +121,618,432)    1,313,374,208 (     +57,389,056) ======
GPU Memory Used:  [6773]
====== after completion "3"                       49,362,423,808 (              +0)    1,313,374,208 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "4"                       49,449,160,704 (     +86,736,896)    1,332,838,400 (     +19,464,192) ======
GPU Memory Used:  [6811]
====== after completion "5"                       49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6811]
====== after completion "6"                       49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6819]
====== after completion "7"                       49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6819]
====== after completion "8"                       49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6819]
====== after completion "9"                       49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6819]
====== after completion "10"                      49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6821]
====== after completion "11"                      49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6821]
====== after completion "12"                      49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6823]
====== after completion "13"                      49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6823]
====== after completion "14"                      49,449,160,704 (              +0)    1,332,838,400 (              +0) ======
GPU Memory Used:  [6825]
====== after completion "15"                      49,449,160,704 (              +0)    1,332,838,400 (              +0) ======

And if i set adapter only once outside the loop, then no increase in gpu memory
====== after completion "0"                       49,362,345,984 ( +34,562,404,352)    1,307,557,888 (    +186,347,520) ======
GPU Memory Used:  [6773]
====== after completion "1"                       49,362,878,464 (        +532,480)    1,308,160,000 (        +602,112) ======
GPU Memory Used:  [6773]
====== after completion "2"                       49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "3"                       49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "4"                       49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "5"                       49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "6"                       49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "7"                       49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "8"                       49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "9"                       49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "10"                      49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "11"                      49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "12"                      49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "13"                      49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "14"                      49,362,878,464 (              +0)    1,308,160,000 (              +0) ======
GPU Memory Used:  [6773]
====== after completion "15"                      49,362,878,464 (              +0)    1,308,160,000 (              +0) ======

Interesting behavior. If i just set one adapter outside the loop and increase the max_tokens=256 and start inference, I see memory increase by 8MB across inference
====== after completion "0"                       49,363,697,664 ( +34,563,756,032)    1,309,958,144 (    +188,268,544) ======
GPU Memory Used:  [6779]
====== after completion "1"                       49,363,697,664 (              +0)    1,309,958,144 (              +0) ======
GPU Memory Used:  [6787]
====== after completion "2"                       49,363,697,664 (              +0)    1,309,958,144 (              +0) ======
GPU Memory Used:  [6795]
====== after completion "3"                       49,363,697,664 (              +0)    1,309,958,144 (              +0) ======
GPU Memory Used:  [6803]
====== after completion "4"                       49,363,832,832 (        +135,168)    1,310,285,824 (        +327,680) ======
GPU Memory Used:  [6811]
====== after completion "5"                       49,363,832,832 (              +0)    1,310,285,824 (              +0) ======
GPU Memory Used:  [6819]
====== after completion "6"                       49,363,832,832 (              +0)    1,310,285,824 (              +0) ======
GPU Memory Used:  [6827]
====== after completion "7"                       49,363,968,000 (        +135,168)    1,310,285,824 (              +0) ======
GPU Memory Used:  [6835]
====== after completion "8"                       49,363,968,000 (              +0)    1,310,285,824 (              +0) ======
GPU Memory Used:  [6843]
====== after completion "9"                       49,397,522,432 (     +33,554,432)    1,310,474,240 (        +188,416) ======
GPU Memory Used:  [6851]
====== after completion "10"                      49,397,657,600 (        +135,168)    1,310,474,240 (              +0) ======
GPU Memory Used:  [6859]
====== after completion "11"                      49,397,657,600 (              +0)    1,310,474,240 (              +0) ======
GPU Memory Used:  [6867]
====== after completion "12"                      49,397,657,600 (              +0)    1,310,474,240 (              +0) ======
GPU Memory Used:  [6875]
====== after completion "13"                      49,431,212,032 (     +33,554,432)    1,310,474,240 (              +0) ======
GPU Memory Used:  [6883]
====== after completion "14"                      49,431,347,200 (        +135,168)    1,310,474,240 (              +0) ======
GPU Memory Used:  [6891]
====== after completion "15"                      49,431,347,200 (              +0)    1,310,474,240 (              +0) ======
GPU Memory Used:  [6899]

Thanks for confirming that. To summarise the info:

when no adapter is used. GPU memory remains constant

when adapter is set. GPU memory increasing constantly
(note: assume this means adapter is set in the loop using the code I sent?)

set adapter only once outside the loop, then no increase in gpu memory

set one adapter outside the loop and increase the max_tokens=256 and start inference, I see memory increase by 8MB across inference

I may try to write the same loop code using the llama.cpp C++ library directly, to try and isolate any issues from the Python bindings in this PR. (You are welcome to have a go with writing C++ if you wish, otherwise I will get to it this week.) I suspect an issue in the llama.cpp C++ layer due to the way it varies with different backends. But we will need a nice repro to isolate that and get help from the llama.cpp devs.
I will try to reproduce on GPU and maybe another backend like Vulkan, since CPU is not showing anything for me.
Another thing you could do perhaps that may clarify when memory is leaked would be to  try logging these messages after any LoRA set adapter calls. That will show memory allocated on the LoRA load operation (if any).
===== after set adapter 2 scale 0.0               4,803,383,296 (              +0)    4,293,046,272 (              +0) ======

Also perhaps we should log or vary the max_tokens since that seems relevant?

All your statements above are true.
I can summarize even further

When no adapter is set, no memory increase
when adapter is set inside or outside the loop and max_tokens=16, memory increases but at a small rate
When adapter is set inside or outside the loop and max_tokens=256, memory increases by about 8Mb for each inference

Can you share how to run llama.cpp cmdline. I can run it on a gpu I have access to

Good idea to try the llama.cpp command line.
The compiled llama.cpp for the Python bindings is in the vendor subdirectory.
There is a normal llama.cpp cli but I'm not sure if it supports running multiple completions in a single session.
Perhaps you can try running the server and then calling it multiple times with curl or via the ui?
It's in the examples/server subdirectory.
https://github.com/ggerganov/llama.cpp/blob/master/examples/server/README.md
You can load a LoRA with --lora or --lora-scaled. It should be possible to set the seed/max tokens etc to match the test case.

Hi @hrsmanian , here is a Bash scrip to test against llama.cpp.
First, compile the llama-server binary. This should be in the llama-cpp-python source directory.
cd vendor/llama.cpp/
make llama-server

Then run the below script, llama-server-memtest.sh.
#!/bin/bash

# Function to clean up server process
cleanup() {
    local exit_code=$?
    echo "Cleaning up..."
    if [ ! -z "$SERVER_PID" ]; then
        kill $SERVER_PID 2>/dev/null
        wait $SERVER_PID 2>/dev/null
    fi
    exit $exit_code
}

# Set up trap for script exit
trap cleanup EXIT

# Start llama-server in background
./llama-server \
  --model "$MODEL_GGUF" \
  --lora "$ADAPTER1_GGUF" &

# Save server PID
SERVER_PID=$!

# Wait for server to start up
sleep 5

# Function to log memory usage
log_memory() {
    local msg=$1
    # Get virtual and resident memory in bytes
    local mem=$(ps -o vsz=,rss= -p $SERVER_PID)
    local vsz=$(echo $mem | cut -d' ' -f1)
    local rss=$(echo $mem | cut -d' ' -f2)

    # Convert to bytes (ps shows KB)
    vsz=$((vsz * 1024))
    rss=$((rss * 1024))

    # Calculate deltas
    if [ -z "$PREV_VSZ" ]; then
        PREV_VSZ=$vsz
        PREV_RSS=$rss
    fi

    local delta_vsz=$((vsz - PREV_VSZ))
    local delta_rss=$((rss - PREV_RSS))

    # Format with commas for readability
    printf "====== %-40s %'16d (%+'16d) %'16d (%+'16d) ======\n" \
        "$msg" $vsz $delta_vsz $rss $delta_rss

    PREV_VSZ=$vsz
    PREV_RSS=$rss
}

# Log initial memory state
log_memory "initial"

# Run completions in a loop
for i in {1..100}; do
    curl --silent --request POST \
        --url http://<IP_ADDRESS>:8080/completion \
        --header "Content-Type: application/json" \
        --data "{\"seed\":12345,\"max_tokens\":16,\"temperature\":0,\"prompt\": \"$i\"}" \
        > /dev/null

    log_memory "after completion \"$i\""
done

When I run it I get output like:
$ ./llama-server-memtest.sh 2>&1 | tee server-memtest.log
...run for awhile...
^C <interrupt>

$ cat server-memtest.log | grep ===
====== initial                                    11,023,482,880 (              +0)    8,471,502,848 (              +0) ======
====== after completion "1"                       11,023,482,880 (              +0)    8,471,502,848 (              +0) ======
====== after completion "2"                       11,090,591,744 (     +67,108,864)    8,471,764,992 (        +262,144) ======
====== after completion "3"                       11,157,700,608 (     +67,108,864)    8,471,896,064 (        +131,072) ======
====== after completion "4"                       11,224,809,472 (     +67,108,864)    8,471,896,064 (              +0) ======
====== after completion "5"                       11,291,918,336 (     +67,108,864)    8,471,896,064 (              +0) ======
====== after completion "6"                       11,291,918,336 (              +0)    8,471,896,064 (              +0) ======
====== after completion "7"                       11,291,918,336 (              +0)    8,471,896,064 (              +0) ======
====== after completion "8"                       11,359,027,200 (     +67,108,864)    8,471,896,064 (              +0) ======
====== after completion "9"                       11,359,027,200 (              +0)    8,471,896,064 (              +0) ======
====== after completion "10"                      11,359,027,200 (              +0)    8,471,896,064 (              +0) ======
====== after completion "11"                      11,359,027,200 (              +0)    8,472,027,136 (        +131,072) ======
====== after completion "12"                      11,359,027,200 (              +0)    8,472,027,136 (              +0) ======
====== after completion "13"                      11,359,027,200 (              +0)    8,472,027,136 (              +0) ======
====== after completion "14"                      11,359,027,200 (              +0)    8,472,027,136 (              +0) ======
...
====== after completion "28"                      11,359,027,200 (              +0)    8,472,027,136 (              +0) ======
====== after completion "29"                      11,359,027,200 (              +0)    8,472,027,136 (              +0) ======
====== after completion "30"                      11,359,027,200 (              +0)    8,472,027,136 (              +0) ======

There is memory growth, but it stabilises after awhile. The server might allocate IO buffers, perhaps it's doing caching, etc. It probably needs more analysis to know if there is a leak. I thought I'd share the script so you can look at GPU memory usage. For a really pure reproduction, we may need to write C++ code that uses the plain llama.cpp API, but testing with the llama-server app first is a good start.


Fix libayatana set icon deprecation

With libayatana-appindicator 0.5.93 building my app fails with linux/flutter/ephemeral/.plugin_symlinks/tray_manager/linux/tray_manager_plugin.cc:126:3: error: 'app_indicator_set_icon' is deprecated: Use app_indicator_set_icon_full instead [-Werror,-Wdeprecated-declarations].
I'm not sure why this only happens now since I checked the changelog and there was nothing suspicious.
The option has been deprecated for 13 years and the new method is also there since then, so it's safe to migrate.

@lijy91  Please merge asap!


[6.0] Add the ability to order by subqueries

This PR adds the ability to order by subqueries  using the existing orderBy($column, $direction = 'asc') and orderByDesc($column) methods.
Previously this was only possible using orderByRaw(), but that's dangerous, as the direction (asc/desc) cannot be set with a binding, meaning developers were responsible for verifying and inserting the direction into the query themselves.
Here are a couple examples of how this can be useful.
// Order users by their last login date
$users = User::orderBy(function ($query) {
    $query->select('created_at')
        ->from('logins')
        ->whereColumn('user_id', 'users.id')
        ->latest()
        ->limit(1);
})->get();

// Order courses by the start date of the first lesson
$courses = Course::orderBy(
    Lesson::select('starts_at')
        ->whereColumn('course_id', 'courses.id')
        ->oldest('starts_at')
        ->limit(1)
)->get();

Note, orderBy() now accepts subqueries in three possible formats:

Illuminate\Database\Query\Builder
Illuminate\Database\Eloquent\Builder
Closure

This is the exact same approach as what's done in the whereIn() method:
https://github.com/laravel/framework/blob/df60917f85cccc489b5223397c1cac9d58acc7ef/src/Illuminate/Database/Query/Builder.php#L856-L864


Design layout

Finish up the design, make it look absolutely gorgeous. Make it look better than your future son.

Closed via #38


[Feature proposal] -  add watch option to config

Add option to config for watching external files.
example
tailwind/backgrounds.js
module.exports = {
	backgroundSize: {
		auto: 'auto',
		cover: 'cover',
		contain: 'contain'
	}
}

tailwind.config
const { backgroundSize } = require('./tailwind/backgrounds')

module.exports = {
    backgroundSize,

    options: {
      watch: 'tailwind/**.js'
    }
}

Cheers

One of the ways:
Add all tailwind.config.js dependencies( = require.js dependencies) here - https://github.com/tailwindcss/tailwindcss/blob/master/src/lib/registerConfigAsDependency.js#L9
@adamwathan What do you think?

Yeah that’s how I’d ideally like to do it but I haven’t been able to figure out a way to determine all of the dependencies of someone’s Tailwind config file. Would love a PR if anyone has an idea of how to do it.
On Aug 10, 2019, 10:35 AM -0400, Serhii Pashchenko<EMAIL_ADDRESS>wrote:

One of the ways:
Add all tailwind.config.js dependencies( = require.js dependencies) here - https://github.com/tailwindcss/tailwindcss/blob/master/src/lib/registerConfigAsDependency.js#L9
@adamwathan What do you think?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

Yeah that’s how I’d ideally like to do it but I haven’t been able to figure out a way to determine all of the dependencies of someone’s Tailwind config file. Would love a PR if anyone has an idea of how to do it.
…
On Aug 10, 2019, 10:35 AM -0400, Serhii Pashchenko @.***>, wrote: One of the ways: Add all tailwind.config.js dependencies( = require.js dependencies) here - https://github.com/tailwindcss/tailwindcss/blob/master/src/lib/registerConfigAsDependency.js#L9 @adamwathan What do you think? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

Cool. I'll try to found a solution 🤔

@adamwathan , I opened PR.

This is just going to work automatically from now on so closing 👍


Need an update for Nim V2

Hello world. This lib is not working on Nim Version 2. I've managed to make it work, but since I'm not the author, I'm not sure if my patches are good enough for a PR.

Hi, are you able to submit a PR for it anyway for reference? Personally I haven't been able to get it working on Nim 2...


Component rendered behind content

I am facing this issue when form-renderer i used for multi select and date component

@Siqlain this is a issue with z-index for datepicker so you can use css to solve this for now. We plan to repalce the multiselect but in is not really a priority but we will get it fixed.

Also ensure all the npm dependencies were installed successfully. That could be another factor.
See how to fix the z-index issue here:
https://github.com/AMPATH/ng2-amrs/blob/master/src/app/patient-dashboard/common/formentry/formentry.component.css#L7

Thank you for the response.. I will try an let you know
Regards ,
Siqlain


[DRAFT] Implement XR_FB_space_warp extension

Adds an extension wrapper implementation of XR_FB_space_warp.
Setup
In order to test AppSW out (compatibility renderer only at the moment):

Build Godot with https://github.com/godotengine/godot/pull/97151
Switch the thirdparty/godot-cpp submodule of this repo to master branch

Then you should be able to build the plugin like normal. Currently in this PR, AppSW is enabled by default, so no need to enable it.
Debug View
I've (minimally) added multiple scenarios of moving elements in the demo project (particles/multimesh/skeleton) for testing purposes. If you'd like a visual of the underlying motion vectors that are generated, you can use the following adb command.
adb shell setprop debug.oculus.spaceWarpDebug 1 && adb shell setprop debug.oculus.MVOverlay 4 && adb shell setprop debug.oculus.MVOverlay.Alpha 0.8 && adb shell input keyevent "KEYCODE_POWER" && adb shell input keyevent "KEYCODE_POWER"

Sometimes I find the project crashes when running the above command, but the debug view is visible upon restarting the app. To exit this view mode you can run:
adb shell setprop debug.oculus.spaceWarpDebug 0 && adb shell input keyevent "KEYCODE_POWER" && adb shell input keyevent "KEYCODE_POWER"

To Do

[ ] Account for locomotion by properly setting appSpaceDeltaPose.
[ ] Enable the use of the XR_COMPOSITION_LAYER_SPACE_WARP_INFO_FRAME_SKIP_BIT_FB flag to skip frames of spacewarp.
[ ] Have the extension not enabled by default, and determine the best way for users to enable/disable it.

@dsnopek I'd done the previous XR sample projects as their own PRs following the merging of the corresponding extensions. I had planned to just keep the simple test scene in the demo project while this PR remained as a draft. I see nothing wrong with expanding on it and just adding an XR sample project to this PR as well though! I will do that.

I've added a fair amount of updates:

Moved the test scene into its own "Meta Space Warp" sample project, included in this PR.

Added a normal, moving MeshInstance3D to the scene
Space warp can now be enabled/disabled by pressing the A button.
Added movement/turning with the analog sticks.
Added a CC0 grass texture behind moving objects so users can see space warp artifacts more easily.

Added a project setting for enabling space warp.
Space warp is now automatically disabled if a non-opengl renderer is being used.
Added a skip_space_warp_frame() function to skip space warp for the following frame.
I believe I'm now accounting for locomotion correctly in appSpaceDeltaPose.

I will open this PR once https://github.com/godotengine/godot/pull/97151 is merged!


Empty Lines Left After Stripping All Imports

I ran into this when using the UP rules to enforce the Python 3.10 typing syntax (discussion), but I believe it applies for all cases when no explicit imports remain.
ruff config, using version 0.0.280
[tool.ruff]
include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"]
line-length = 120
select = [
    # pyflakes
    "F",
    # pycodestyle
    "E", "W",
    # flake8-2020
    "YTT",
    # flake8-bugbear
    "B",
    # flake8-commas
    "COM",
    # flake8-datetimez
    "DTZ",
    # flake8-debugger
    "T10",
    # flake8-gettext
    "INT",
    # flake8-quotes
    "Q",
    # pylint
    "PL",
    # misc lints
    "PIE",
    # flake8-pyi
    "PYI",
    # tidy imports
    "TID",
    # implicit string concatenation
    "ISC",
    # type-checking imports
    "TCH",
    # isort
    "I",
    # comprehensions
    "C4",
    # pygrep-hooks
    "PGH",
    # Ruff-specific rules
    "RUF",
    # Upgrade syntax
    "UP",
]
ignore = [
    # module level import not at top of file
    "E402",
    # too many arguments to function call
    "PLR0913",
    # too many statements in function
    "PLR0915",
    # magic value used in comparison,
    "PLR2004",
    # do not use mutable data structures for argument defaults
    "B006",
]
per-file-ignores = {"__init__.py" = ["F401"]}
target-version = "py310"

Starting file, dummy.py:
from typing import Union

def dummy(a: Union[int, None]) -> str:
    return str(a)

After running ruff dummy.py --fix:

def dummy(a: int | None) -> str:
    return str(a)

This whitespace at the top of the file persists for any future ruff runs.
Perhaps this isn't truly a bug since there isn't a rule for whitespace at the top of a file, but given that prior to stripping the import I had my file start at line 1, it feels unnatural for the remaining code to start after the two-line whitespace.

Definitely appreciate that this isn't ideal, but right now it's considered "working as intended". We make a best effort to produce clean changes on-fix (e.g., we avoid leaving trailing whitespace after removing the imports), but the intention is that you run a formatter over your code post-fix to clean up any stylistic / formatting changes.


chore: add deprecation warning to ESM methods

Modifies ESM methods to add a compiler deprecation warning. Instructs users to use the Stable Regions instead.

Ok, turns out this doesn't work out of the box because deprecation comments are only honoured on module fields, not top-level declarations as in prim.mo.
I've hacked the compiler to allow this, but now think this might not be the way to go after all. All user level deprecation messages share the same error code, so it would be hard or ugly to reliably filter out the stable memory ones, and the message now complains about the Prim.stableMemoryXXX operations being used by ESM.
A more direct approach might be to split the  stable memory prims into a separate file, as we do for timers, and only include them when --experimental-stable-memory is enabled on the moc command line, opting in to the old feature and disabling it otherwise. Other code that imports ESM without specifying the flag will get a hard error about an unknown Prim.stableMemoryXXX rather than a warning. Will need to think about some more.


Worker fails while sending outcome message due to too long error traceback(?)

Saw my workers crashing most likely due permission errors. But the error in the worker logs came from SQS, complaining that the message sent to SQS was longer than 256kB. So that's gotta be the outcome with the error traceback? I have no clue why the compressed(!) traceback would become that big...

Interesting. Should we log the traceback before posting it to the outcome queue?


Add log module and tests

Changes Unknown when pulling ffbbe77a52584b5a2a7398b17816b1cbcaaac412 on add-logger into ** on master**.

Changes Unknown when pulling a1d3cb35fceac3beefeddea3ede04d6a1da843b3 on add-logger into ** on master**.


fix: fix transactions to rollback on failure

When we have a transaction fail we should roll back the transaction.

I don't immediately see why this is necessary. If the DBSession is dropped without committing the transaction (which happens if the process short-circuits due to an error) then it should roll-back automatically.

I've been seeing issues with the transactions not being closed after failure, so I added this code to explicitly close them. It appears that the connections are returned to the pool with the transaction still being active.

I'm seeing errors like this.
`Traceback (most recent call last):
File "/cloudagent/aries_cloudagent/wallet/askar.py
line 199, in create_local_did
await self._session.handle.insert_key(
File "/usr/local/lib/python3.10/site-packages/aries_askar/store.py
line 498, in insert_key
await bindings.session_insert_key(
File "/usr/local/lib/python3.10/site-packages/aries_askar/bindings.py
line 857, in session_insert_key
await do_call_async(
aries_askar.error.AskarError: Backend error
Caused by: error returned from database: current transaction is aborted, commands ignored until end of transaction block
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/cloudagent/aries_cloudagent/protocols/didexchange/v1_0/routes.py
line 151, in didx_accept_invitation
request = await didx_mgr.create_request(
File "/cloudagent/aries_cloudagent/protocols/didexchange/v1_0/manager.py
line 270, in create_request
my_info = await wallet.create_local_did(
File "/cloudagent/aries_cloudagent/wallet/askar.py
line 207, in create_local_did
raise WalletError("Error inserting key") from err
aries_cloudagent.wallet.error.WalletError: Error inserting key
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/ddtrace/contrib/aiohttp/middlewares.py
line 61, in attach_context
response = await handler(request)
File "/cloudagent/aries_cloudagent/admin/server.py
line 159, in ready_middleware
return await handler(request)
File "/cloudagent/aries_cloudagent/admin/server.py
line 196, in debug_middleware
return await handler(request)
File "/usr/local/lib/python3.10/site-packages/aiohttp_apispec/middlewares.py
line 45, in validation_middleware
return await handler(request)
File "/cloudagent/aries_cloudagent/admin/server.py
line 339, in check_multitenant_authorization
return await handler(request)
File "/cloudagent/aries_cloudagent/admin/server.py
line 383, in setup_context
return await task
File "/cloudagent/aries_cloudagent/protocols/didexchange/v1_0/routes.py
line 161, in didx_accept_invitation
raise web.HTTPBadRequest(reason=err.roll_up) from err
aiohttp.web_exceptions.HTTPBadRequest: Error inserting key. Backend error. Caused by: error returned from database: current transaction is aborted, commands ignored until end of transaction block.
`

Hm, it looks like this might be the bit that needs fixing (txn_depth > 1). I can test that out and maybe get rid of the false_txn flag.
impl<'a, DB: ExtDatabase> Drop for DbSessionActive<'a, DB> {
    fn drop(&mut self) {
        if self.txn_depth > 1 && !self.false_txn {
            info!("Roll-back dropped nested transaction");
            DB::TransactionManager::start_rollback(self.connection_mut());
        }
    }
}

I added another PR: https://github.com/hyperledger/aries-askar/pull/45 if you'd like to test that.

I'll test that.


Splitting up the WRF docker build

The WRF docker is building more than just WRF - so I wonder if we can split some items out?
https://github.com/UoMResearchIT/EMEP-docker/blob/master/WRF/Dockerfile

zlib - needed
libpng - needed
jasper - needed
hdf5 - needed
netcdf - needed
mpich - needed
NCEPlibs - move out
UPP - move out
ARWpost - move out
OpenGrADS - move out
g2ctl - move out
wgrib2 - perhaps needed later?
WRF - needed
WPS - needed (check why 4.3.1 and not 4.3.3?)
WPSPLUS - needed later, leave out for now
WPSPLUS 4DVAR - needed later, leave out for now

NCEPlibs, UPP, ARWpost, OpenGrADS, and g2ctl are useful for post-processing WRF data - I don't think they need to be in the WRF/WPS docker though.
wgrib2 is used for working with GRIB-2 data files, but for the basic creation of WRF input files WPS should suffice (and I think, perhaps, wgrib2 is used more for supporting OpenGrADS work?).
WPSPLUS and WPSPLUS 4DVAR will be useful for many users - but aren't needed (yet) for our usecase, as they deal with data assimulation for forecasting. If they cause any issues for building the docker container then leave them out for now.

I would also see about adding obsgrid for wrf.
Then the wrf docker will only have the main components for any wrf build.


Fixing the documentation link in Cargo.toml

This link doesn't seem to be correct and this is leading to the link on crates.io pointing to the wrong place, I believe.

Thanks for noticing! It's always hard to keep track of all the dead links…


Bug: unresponsive under Ventura

eqmac becomes unresponsive under Ventura
Steps to Reproduce
Steps to reproduce the behaviour (feel free to change the placeholder as you need):

Boot ventura
Load emac
Enable key control
Works great for a bit
Stops changing volumes with keys
Wheel of death with cursor over menu bar icon
Hangs on restart

Expected behaviour
It just works under Monterey
Setup information:

HDMI and other speakers
macOS Version: [13beta]
eqMac Version [1.4.6, driver 2.0.5]
eqMac UI Version [3.2.4]

Screenshots or Console.app logs
If applicable, add screenshots to help explain your problem. Also you can run Console.app and apply filter for eqMac
Additional information
Add any other context about the problem here.
eqMac_2022-06-11-092942_Neptune.sin.txt

Hi all, I am closing this issue since the latest versions are way more stable now, if there is any other related issue, please browse for a similar open issue and comment on it. If there are none, please create a new one. Thanks!


feat: add official Scalar .NET integration

we woke up today to a wonderful guide written on how to add Scalar to .NET with the anticipation of the amazing new 9.0 release with OpenAPI support out of the box!
@captainsafia wrote the wonderful docs and the integration for Scalar, now its bundled and available as a package so we can add more functionality with config, we also added it to the root README.
some things left to do:

[ ] custom CDN
[ ] custom page title
[ ] maybe a generic to handle the scalar config object?

awesome! i added some github issues so we can fast follow and get this in! ✨
https://github.com/scalar/scalar/issues/1738
https://github.com/scalar/scalar/issues/1739
https://github.com/scalar/scalar/issues/1740

@marclave is possible to use with dotnet 8?

@marclave is possible to use with dotnet 8?

yes you can use it with version 8 in the latest nuget release ✨

I was able to use it on dotnet 8, but I also needed to use Swagger to generate the open API json file. Is it possible to use without Swagger?
How do I generate the json file?

@marclave I think to support this fully in .NET 8, the Scalar.AspNetCore package would need to support a way to set the data-url here:
https://github.com/scalar/scalar/blob/e2905ac1aba39f3a9542349d5137933b8178b3bd/packages/scalar.aspnetcore/Scalar.AspNetCore.cs#L45
So that we can point it at the OpenAPI file created in packages other than Microsoft.AspNetCore.OpenApi (which is only supported in .NET 9).

@captainsafia @renerlemes we added the options to the package but we need to add some documentation
https://github.com/scalar/scalar/blob/main/packages/scalar.aspnetcore/ScalarOptions.cs
I will add some today :) but you can pass in the data url ✨

@marclave and @captainsafia thanks for support. I´ll try to use again.
With this change they made, will I still need the Swagger package to generate the Open API File and pass in the data url?
When you do the documentation, if you can inform me here and I will do new tests.

@renerlemes Did you ever figure out how to use this in .NET 8? I am trying to do that as well, and am hitting a brick wall so far

With this change they made, will I still need the Swagger package to generate the Open API File and pass in the data url?

Yes, you'll still need to use a separate package to generate the OpenAPI document that Scalar is consuming. If you're targeting .NET 8 or below, you can use Swashbuckle or NSwag to generate the packages. If you're using .NET 9, you can use the support in the built-in Microsoft.AspNetCore.OpenApi package (see here).

@renerlemes Did you ever figure out how to use this in .NET 8? I am trying to do that as well, and am hitting a brick wall so far

If you're running into issues that are more specific to .NET, feel free to file an issue on the dotnet/aspnetcore repo and I'd be happy to help.

Thanks @captainsafia! The issue I run into is with Scalar. I cannot set the data-url, which is "/swagger/v1/swagger.json". The pattern for this in Scalar seems to be (as you pointed out in an earlier post) as specified here: https://github.com/scalar/scalar/blob/e2905ac1aba39f3a9542349d5137933b8178b3bd/packages/scalar.aspnetcore/Scalar.AspNetCore.cs#L45
And that data-url does not match my pattern at all. Can we set the whole data-url using the ScalarOptions.cs class?

@steingran Ah, you're right.
@marclave Are you open to making the data-url customizable as well? If so, I'd be happy to open a PR.

@steingran Ah, you're right.
@marclave Are you open to making the data-url customizable as well? If so, I'd be happy to open a PR.

absolutely open! ✨

@marclave we should include how to use Scaler with .NET 8 in the documentation, i myself had very hard time figuring out how to use Scaler with .NET 8.
very few people use .NET 9 preview so i would be happy to work on this issue

@marclave we should include how to use Scaler with .NET 8 in the documentation, i myself had very hard time figuring out how to use Scaler with .NET 8. very few people use .NET 9 preview so i would be happy to work on this issue

hi @HalfToothed ! that would be amazing! Were the main friction points around a lack of documentation?

Yes @marclave  in documentation this is the only example which shows how to integrate scaler with .NET.

we can provide another example using .NET 8
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseScalar();
}

app.MapControllers();

app.Run();

@marclave I can help you add additional documentation on this if you'd like.
This is mostly about showing people how to use the new data-url options I just added in https://github.com/scalar/scalar/pull/2722 since some OpenAPI packages in .NET host their JSON file at a different endpoint in the app.

@captainsafia ya sure, i should create a new issue for updating the docs of .NET only ?


VDC Marketplace solutions deploy fails on testnet

Description
When deploying a solution from the vdc marketplace dashboard fails.

Traceback/Logs/Alerts
When accessing the machine to debug the following error is thrown:
2021-01-19 09:37:25.075 | ERROR    | jumpscale.sals.chatflows.chatflows:wrapper:173 - error
Traceback (most recent call last):

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/sals/chatflows/chatflows.py", line 202, in wrapper
    self._execute_current_step(spawn=False)
    │    └ <function GedisChatBot._execute_current_step at 0x7f669b817f70>
    └ <vdc_dashboard.chats.cryptpad.CryptpadDeploy object at 0x7f66995fe250>

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/sals/chatflows/chatflows.py", line 210, in _execute_current_step
    wrapper(step_name)
    │       └ 'create_subdomain'
    └ <function GedisChatBot._execute_current_step.<locals>.wrapper at 0x7f6699833a60>

> File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/sals/chatflows/chatflows.py", line 147, in wrapper
    getattr(self, step_name)()
            │     └ 'create_subdomain'
            └ <vdc_dashboard.chats.cryptpad.CryptpadDeploy object at 0x7f66995fe250>

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/sals/chatflows/chatflows.py", line 668, in wrapper
    return func(*args, **kwargs)
           │     │       └ {}
           │     └ (<vdc_dashboard.chats.cryptpad.CryptpadDeploy object at 0x7f66995fe250>,)
           └ <function SolutionsChatflowDeploy.create_subdomain at 0x7f669966f700>

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/packages/vdc_dashboard/sals/solutions_chatflow.py", line 287, in create_subdomain
    self._get_domain()
    │    └ <function SolutionsChatflowDeploy._get_domain at 0x7f669966f310>
    └ <vdc_dashboard.chats.cryptpad.CryptpadDeploy object at 0x7f66995fe250>

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/packages/vdc_dashboard/sals/solutions_chatflow.py", line 117, in _get_domain
    gateways = deployer.list_all_gateways(self.username, PREFERRED_FARM, identity_name=self.identity_name)
    │          │        │                 │    │         │                             │    └ 'vdc_ident_4308ae733aba4c48b6635f09be8dd924'
    │          │        │                 │    │         │                             └ <vdc_dashboard.chats.cryptpad.CryptpadDeploy object at 0x7f66995fe250>
    │          │        │                 │    │         └ 'csfarmer'
    │          │        │                 │    └ 'ranatarek'
    │          │        │                 └ <vdc_dashboard.chats.cryptpad.CryptpadDeploy object at 0x7f66995fe250>
    │          │        └ <function MarketPlaceDeployer.list_all_gateways at 0x7f669973e9d0>
    │          └ <jumpscale.sals.marketplace.deployer.MarketPlaceDeployer object at 0x7f66998acca0>
    └ {}

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/sals/marketplace/deployer.py", line 185, in list_all_gateways
    gateways_pools = self._get_gateways_pools(farm_name, identity_name)  # Empty pools contains the gateways only
                     │    │                   │          └ 'vdc_ident_4308ae733aba4c48b6635f09be8dd924'
                     │    │                   └ 'csfarmer'
                     │    └ <function MarketPlaceDeployer._get_gateways_pools at 0x7f669973e940>
                     └ <jumpscale.sals.marketplace.deployer.MarketPlaceDeployer object at 0x7f66998acca0>

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/sals/marketplace/deployer.py", line 158, in _get_gateways_pools
    farms_names_with_gateways = set(

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/sals/marketplace/deployer.py", line 159, in <lambda>
    map(lambda farm_id: deployer._explorer.farms.get(farm_id=farm_id).name, farms_ids_with_gateways)
               │        │        │                   │       └ 71
               │        │        │                   └ 71
               │        │        └ <property object at 0x7f669988ba90>
               │        └ <jumpscale.sals.marketplace.deployer.MarketPlaceDeployer object at 0x7f66998acca0>
               └ 71

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/clients/explorer/farms.py", line 103, in get
    resp = self._session.get(f"{self._url}/{farm_id}")
           │    │        └ <function Session.get at 0x7f669e270af0>
           │    └ <requests.sessions.Session object at 0x7f66995f3670>
           └ <jumpscale.clients.explorer.farms.Farms object at 0x7f66995f3f70>

  File "/usr/local/lib/python3.8/dist-packages/requests/sessions.py", line 543, in get
    return self.request('GET', url, **kwargs)
           │    │              │      └ {'allow_redirects': True}
           │    │              └ 'https://explorer.testnet.grid.tf/api/v1/farms/71'
           │    └ <function Session.request at 0x7f669e270a60>
           └ <requests.sessions.Session object at 0x7f66995f3670>
  File "/usr/local/lib/python3.8/dist-packages/requests/sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
           │    │    │       └ {'timeout': None, 'allow_redirects': True, 'verify': True, 'proxies': OrderedDict(), 'stream': False, 'cert': None}
           │    │    └ <PreparedRequest [GET]>
           │    └ <function Session.send at 0x7f669e270ee0>
           └ <requests.sessions.Session object at 0x7f66995f3670>
  File "/usr/local/lib/python3.8/dist-packages/requests/sessions.py", line 650, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
    │   │                         │      │    └ {'timeout': None, 'verify': True, 'proxies': OrderedDict(), 'stream': False, 'cert': None}
    │   │                         │      └ <Response [404]>
    │   │                         └ {'response': [<function log_request at 0x7f669bd7ea60>, <function raise_for_status at 0x7f669bef8700>]}
    │   └ <function dispatch_hook at 0x7f669e2cdca0>
    └ <Response [404]>
  File "/usr/local/lib/python3.8/dist-packages/requests/hooks.py", line 31, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
    │            │    │            └ {'timeout': None, 'verify': True, 'proxies': OrderedDict(), 'stream': False, 'cert': None}
    │            │    └ <Response [404]>
    │            └ <function raise_for_status at 0x7f669bef8700>
    └ None

  File "/sandbox/code/github/threefoldtech/js-sdk/jumpscale/clients/explorer/errors.py", line 23, in raise_for_status
    raise HTTPError(http_error_msg, response=resp)
          │         │                        └ <Response [404]>
          │         └ '404 Client Error: mongo: no documents in result for url: https://explorer.testnet.grid.tf/api/v1/farms/71'
          └ <class 'requests.exceptions.HTTPError'>

requests.exceptions.HTTPError: 404 Client Error: mongo: no documents in result for url: https://explorer.testnet.grid.tf/api/v1/farms/71

worked with rebasing development_vdc branch with development fix to include https://github.com/threefoldtech/js-sdk/commit/80d7f2a0e793efa38c0405fd3dd4b54b09b259d9

worked with rebasing development_vdc branch with development fix to include https://github.com/threefoldtech/js-sdk/commit/80d7f2a0e793efa38c0405fd3dd4b54b09b259d9


resolve depcheck warnings

$ npx depcheck
Unused dependencies
* @oclif/config
* @oclif/errors
* @oclif/plugin-help
* zlib
Missing dependencies
* execa: ./e2e/e2e.js
* lodash: ./src/client.js
* @adobe/aio-cli-plugin-config: ./test/fixtures/scripts/global-setup.js

devDep warnings removed because I think they are false positives.

@oclif/plugin-help is a false positive as well. This is a peer dependency of @oclif/command and if not listed, causes a warning on install.
Rest of these are fixed by #113


Add API environment information to dev/staging

Currently we use the production API in the staging environment. However this can change based on our feedback needs.
We should add the information about which API is currently in use in dev/staging. (do not show in prod environment)

Added to the banner.


LaTeX support?

Love the style. Just made my personal website with it. Are there any plans to support LaTeX in the future? Or is that feature already supported?

Thank you, @wrshoemaker  - I don't know how to do that. Maybe @rdwatters knows?

I have very little knowledge of LaTeX. Sorry @wrshoemaker, @budparr I've used a hack with Pandoc, Word default styles, and some ugly AppleScript when I needed to generate both HTML pages and PDF from a single markdown file.
I'm sure a LaTeX guru could make quick work of this with custom outputs, but in 2017, I feel like it's a better use of time to focus on a solid print stylesheet in the event users want to Ctrl+P>Save to PDF...and most of my use cases don't care printing and print formats, TBH...

Not sure if this can be streamlined, but the following worked for me.

Add this code snippet in the "partials":

    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
        tex2jax: {
          <!-- inlineMath: [['$','$'], ['\\(','\\)']], -->
          <!-- displayMath: [['$$','$$'], ['\\[','\\]']], -->
          processEscapes: true,
          processEnvironments: true,
          skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
          TeX: { equationNumbers: { autoNumber: "AMS" },
          extensions: ["AMSmath.js", "AMSsymbols.js"] }
          },
        CommonHTML: { linebreaks: { automatic: true } },
        "HTML-CSS": { linebreaks: { automatic: true } },
        SVG: { linebreaks: { automatic: true } }
      });
    </script>
    <script type="text/javascript" async
            src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML">
    </script>

Add markup: mmark at the beginning of the post:

date: 2017-11-15T00:17:23Z
markup: mmark
draft: false

Enclose equations in dollars:

$$\varphi = \frac{1}{\varphi-1}$$
Example is from here, code here.
The only part where the theme could help is in including the code snippet above by default I guess.


Segmentation Fault when adding breakpoint()

Hello, I am getting a Segmentation Fault when placing breakpoints() anywhere within train_eval() or child functions therein (such as tools.simulate()). I initially thought it was an issue with torch.compile(), but the issue persists with and without torch.compile().
I'm curious if anyone else has seen something similar, and know of a possible reason/fix?

Hello,
If you have any updates about that  Segmentation Fault, it would be helpful to know.


Swerve Drive

Summary
Make a working swerve drive for the B team robot. I don't really know anything
Work Scope

Create new drive command for swerve drive
to be continued

Verification
The robot will drive correctly and not fail.

I set this to close, but we should keep it open to ensure the integration with actual hardware goes well


Badge request: GitHub merged pull requests

:clipboard: Description
I would like a badge that counts all of the pull requests that was merged only, the closed pr badge could be changed I think to filter out merged prs.

The badge is for GitHub.
What sort of information should this badge show?
The badge should contain the count of merged pull requests, also the count of merged pull requests could also be used to subtract from the closed pull request badge to (or well make a version of it that excludes merged prs).

:link:
Where can we get the data from?
list the pull requests first using GET https://api.github.com/repos/{owner}/{repo}/pulls then request:
GET https://api.github.com/repos/{owner}/{repo}/pulls/{pull_number}/merge

Is there a public API?
yes

Does the API requires an API key?
Nope.

Link to the API documentation.
https://docs.github.com/en/rest/reference/pulls#list-pull-requests
https://docs.github.com/en/rest/reference/pulls#check-if-a-pull-request-has-been-merged

:microphone: Motivation
I noticed that we could show up opened, closed issues and pull requests among other things however lacked the ability to get a badge for merged pull requests.

What is the specific use case?
People like me want to show that we merge pull requests a ton and it would support those who feel like contributing to projects too.

It seems there is another way as well to -> https://github.com/Elskom/Sdk/pulls?q=is%3Apr+is%3Aclosed+is%3Aunmerged
returns only unmerged pr's while -> https://github.com/Elskom/Sdk/pulls?q=is%3Apr+is%3Aclosed+is%3Amerged
returns only merged.

Thanks! I think that the API information is not correct for what you're asking for though, or at least not a viable option.
We actually already support distinguishing between merged vs. closed for individual PRs
https://github.com/badges/shields/pull/6159
https://img.shields.io/github/pulls/detail/state/badges/shields/6159

https://github.com/badges/shields/pull/6161
https://img.shields.io/github/pulls/detail/state/badges/shields/6161

The difference here is the desire to filter against the total PR count for merged vs. closed, and this is actually much simpler to do via the v4/GraphQL API. Fortunately, our existing badge that reports total for both issues and PRs already does this!
https://github.com/badges/shields/blob/d4116b3ab0bb05fdad5695b5f884b38b6f4af954/services/github/github-issues.service.js#L332-L349
Think all that would be needed to make this happen is an additional route variant (issues-pr-merged, for consistency)
https://github.com/badges/shields/blob/d4116b3ab0bb05fdad5695b5f884b38b6f4af954/services/github/github-issues.service.js#L42-L46
and then tweaking the respective signatures to support passing through the merged-only option, and using the state filters accordingly:
https://github.com/badges/shields/blob/d4116b3ab0bb05fdad5695b5f884b38b6f4af954/services/github/github-issues.service.js#L345-L348
closed = merged+closed states
merged = merged state
otherwise open state

@calebcartwright can we also do an issues-pr-closed-unmerged too?

issues-pr-closed-unmerged too eventually?

would probably need to bikeshed on the name a bit, but i don't see why not!

It seems there is another way as well to -> https://github.com/Elskom/Sdk/pulls?q=is%3Apr+is%3Aclosed+is%3Aunmerged
returns only unmerged pr's while -> https://github.com/Elskom/Sdk/pulls?q=is%3Apr+is%3Aclosed+is%3Amerged
returns only merged.

You can use these queries with the custom issue search badge e.g:
 - https://img.shields.io/github/issues-search/Elskom/Sdk?label=unmerged PRs&query=is%3Apr is%3Aclosed is%3Aunmerged
 - https://img.shields.io/github/issues-search/Elskom/Sdk?label=merged PRs&query=is%3Apr+is%3Aclosed+is%3Amerged

Good point Chris. Do you think we should go ahead and close this (folks can always use the color query param if they want it to have the same purple color) or would it be worthwhile to make those options available like the other PR aggregate status badges?

I would like the options available like the other pr aggregate badges.

https://github.com/badges/shields/blob/master/services/github/github-issues-search.service.js#L26-L28
I see from here it does not let you set text at the end.

I see from here it does not let you set text at the end, perhaps have an optional query param for it that defaults to nothing?.

No, this is by design. We do not allow open ended badge message customization #6135. For the issues status badges, we have two kinds, one that puts the status in the label (raw) and another that puts it as a suffix in the message:
https://img.shields.io/github/issues-pr-raw/badges/shields

https://img.shields.io/github/issues-pr/badges/shields

the former is already possible via the issue search badge and query params as noted above, the latter would not be.
i'm not personally opposed to to including the additional PR status variants, but it does seem like quite a bit of overhead just to get the non-raw versions (status on the message)

This issue seems like it was solved.
Can I suggest closing it?

This issue seems like it was solved. Can I suggest closing it?

Thanks for the question! However, no, I don't see this as resolved.
It's often the case that there's a viable alternative/workaround available via existing features such as our dynamic badge features (or custom endpoint), but that doesn't inherently negate/resolve the request for a native badge.
This issue was requesting a native badge that doesn't yet exist (though which has some alternative as noted earlier in the thread). From the maintainer side we've not explicitly said "no we won't do this", and the author hasn't changed their mind yet either and closed the issue themselves.
I don't anticipate the issue being closed unless and until one of those two things happen, or unless someone implements the requested badge.

Noted 👍
On Thu, May 12, 2022, 3:54 PM Caleb Cartwright @.***>
wrote:

This issue seems like it was solved. Can I suggest closing it?
Thanks for the question! However, no, I don't see this as resolved.
It's often the case that there's a viable alternative/workaround available
via existing features such as our dynamic badge features (or custom
endpoint), but that doesn't inherently negate/resolve the request for a
native badge.
This issue was requesting a native badge that doesn't yet exist (though
which has some alternative as noted earlier in the thread). From the
maintainer side we've not explicitly said "no we won't do this", and the
author hasn't changed their mind yet either and closed the issue themselves.
I don't anticipate the issue being closed unless and until one of those
two things happen, or unless someone implements the requested badge.
—
Reply to this email directly, view it on GitHub
https://github.com/badges/shields/issues/6164#issuecomment-1125412511,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AHGOB42EXUKQ2IKRXFMWJ33VJVVYRANCNFSM4XP4JFUA
.
You are receiving this because you commented.Message ID:
@.***>

I would like to work on this one :)


Moving workflow between project will not move TLS certificates (will have no access to them)

Rancher versions:
rancher/rancher:latest (2.0.2 I believe)
rancher/rancher-agent:v2.0.2
Setup details: (single node rancher vs. HA rancher, internal DB vs. external DB)
HA rancher
Steps to Reproduce:
Works for anything, I'll use longhorn as an example. Install Longhorn, create separate TLS certificate (manually), move longhorn namespace to the new project. Edit ingress.
Results:
Rancher will not see TLS certificate, assigned to Longhorn ingress and will remove it.

If workflow has been deployed from catalog and moved, it will stuck in original project

Link to https://github.com/rancher/rancher/issues/13931


Avoid using time.After() in select statements

Expected Behavior
 time.After() is not used in select statements
Actual Behavior
Steps to Reproduce the Problem
For instance: https://github.com/tektoncd/pipeline/blob/99b8b196ea753af36befda8c0e0e1eaa9490ae68/pkg/pipelinerunmetrics/metrics.go#L290-L300
Additional Info
Tekton Pipeline version: v0.33 -> v0.38
From the security audit:

Calls to time.After in for/select statements can lead to memory leaks because the garbage collector does not clean up the underlying Timer object until the timer fires. A new timer, which requires resources, is initialized at each iteration of the for loop (and, hence, the select statement). As a result, many routines originating from the time.After call could lead to overconsumption of the memory.

Short term, consider refactoring the code that uses the time.After function in for/select loops using tickers. This will prevent memory leaks and crashes caused by memory exhaustion.
Long term, ensure that the time.After method is not used in for/select routines. Periodically use the Semgrep query to check for and detect similar patterns.

This looks like a good explanation of the issue, and possible alternative using time.NewTicker: https://www.arangodb.com/2020/09/a-story-of-a-memory-leak-in-go-how-to-properly-use-time-after/

/assign


Make router deterministic.

See the documentation for details.
But in a nutshell, this PR changes the behavior and how you use the Router.

Before

app({
  view: {
    "/": defaultView,
    "/dashboard": dashboardView,
    "/billing": billingView
  },
  plugins:[Router]
})

After

app({
  view: [
    ["/", defaultView],
    ["/dashboard", dashboardView],
    ["/billing", billingView],
    ["*", errorView]
  ],
  plugins: [Router]
})

This is a bit more verbose, but it makes the router route resolution deterministic.
Bundle increase: 13 bytes. 💥
@igl Ping.

To sugarcoat the API even further:
app({
  view: Router
    .on("/", defaultView)
    .on("/dashboard", dashboardView)
    .on("/billing", billingView)
    .on("*", errorView),
  plugins: [Router]
})

We could do something like this:
Router.on = function on(route, view, parent) {
  ;(parent ? parent : (parent = []))[parent.length] = [route, view]
  parent.on = function(route, view) {
    return on(route, view, parent)
  }
  return parent
}

@jbucaran I'd still prefer something like React Router 4.
{view :
	<div>
		<Route match="/" exact>Index</Route>
		<Route match="/:something">{state.router.params.something}</Route>
	</div>
}

@dodekeract This could basically already be done by removing the render piece of the router plugin, so its only job is mapping the url bar to a state object.
That <Route match="/"> tag is just a simple function, then, unless I'm missing something?  I haven't really played with React Router since v2 or so.
{
  view:
        h('div', {}, [
          state.router.match === "/" ? "Index" : null,
          state.router.match === "/:something" ? state.router.params.something : null
        ])
}

@dodekeract Maybe someday or maybe as a separate "advanced" router plugin. It would be awesome to have a react-router like router for hyperapp, but our default router is rather simplistic.

Closing in favor of #214.


Feature/dev 6513a

Re fixed prelimary data for line charts and legend builded.

@Atash3000 closing this PR since you had 6513b opened. If anything needs to be added from this PR let me know, but I think we're good.


Roll Flutter Engine from 3c6a373bda3e to 1f0f950ea02a (1 revision)

https://github.com/flutter/engine/compare/3c6a373bda3e...1f0f950ea02a
2024-07-04<EMAIL_ADDRESS>Roll Skia from 72b2ea81c959 to abda211b2753 (1 revision) (flutter/engine#53732)
If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC aaclarke@google.com,rmistry<EMAIL_ADDRESS>on the revert to ensure that a human
is aware of the problem.
To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose
To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622
Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md

Commit queue failed; closing this roll.


Support explicitly implemented interfaces in TypeBinder

Adds support for serializing explicitly implemented interface properties and leverages this support in Tables for ITableEntity.
fixes https://github.com/Azure/azure-sdk-for-net/issues/26514

API change check
API changes are not detected in this pull request.


kube-vip never establishing session with FortiGate

I've set up a new cluster with kubeadm and have been bashing my head against the wall for the last couple hours trying to work out why I cannot make kube-vip peer with my FortiGate.
On the kube-vip side I get endless log spam of the BGP connection routine as such
2023/04/23 13:16:45 type:STATE peer:{conf:{local_asn:4210001021 neighbor_address:"<IP_ADDRESS>" peer_asn:4200001000} state:{local_asn:4210001021 neighbor_address:"<IP_ADDRESS>" peer_asn:4200001000 session_state:IDLE router_id:"<nil>"} transport:{local_address:"<IP_ADDRESS>" local_port:41475 remote_port:179}}
2023/04/23 13:16:50 type:STATE peer:{conf:{local_asn:4210001021 neighbor_address:"<IP_ADDRESS>" peer_asn:4200001000} state:{local_asn:4210001021 neighbor_address:"<IP_ADDRESS>" peer_asn:4200001000 session_state:ACTIVE router_id:"<nil>"} transport:{local_address:"<IP_ADDRESS>" local_port:41475 remote_port:179}}
2023/04/23 13:16:59 type:STATE peer:{conf:{local_asn:4210001021 neighbor_address:"<IP_ADDRESS>" peer_asn:4200001000} state:{local_asn:4210001021 neighbor_address:"<IP_ADDRESS>" peer_asn:4200001000 session_state:OPENSENT router_id:"<nil>"} transport:{local_address:"<IP_ADDRESS>" local_port:38051 remote_port:179}}

with the FortiGate perpetually saying
BGP: <IP_ADDRESS>-Outgoing [FSM] State: Active Event: 9
BGP: <IP_ADDRESS>-Outgoing [FSM] State: Connect Event: 9
BGP: <IP_ADDRESS>-Outgoing [NETWORK] FD=31, Sock Status: 111-Connection refused
BGP: <IP_ADDRESS>-Outgoing [FSM] State: Connect Event: 18

for all 3 nodes.
I notice that kube-vip is never actually listening for incoming BGP messages, only whatever :2112 is used for (I presume the leader election process) and have dug into the code to find that its explicitly set to not listen for BGP on TCP 179 and I feel like this could be part of the problem, the FortiGate needs to be able to talk to the other end in order to establish a session.
Static Pod Manifest generated as per the docs
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  name: kube-vip
  namespace: kube-system
spec:
  containers:
  - args:
    - manager
    env:
    - name: vip_arp
      value: "false"
    - name: port
      value: "6443"
    - name: vip_interface
      value: lo
    - name: vip_cidr
      value: "32"
    - name: cp_enable
      value: "true"
    - name: cp_namespace
      value: kube-system
    - name: vip_ddns
      value: "false"
    - name: svc_enable
      value: "true"
    - name: bgp_enable
      value: "true"
    - name: bgp_routerid
      value: <LOCAL ID>
    - name: bgp_as
      value: "<LOCAL AS>"
    - name: bgp_peeraddress
    - name: bgp_peerpass
    - name: bgp_peeras
    - name: bgp_peers
      value: <ROUTER>,<OTHER NODES>
    - name: address
      value: <VIP>
    - name: prometheus_server
      value: :2112
    image: ghcr.io/kube-vip/kube-vip:v0.5.12
    imagePullPolicy: Always
    name: kube-vip
    resources: {}
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
        - NET_RAW
    volumeMounts:
    - mountPath: /etc/kubernetes/admin.conf
      name: kubeconfig
  hostAliases:
  - hostnames:
    - kubernetes
    ip: <IP_ADDRESS>
  hostNetwork: true
  volumes:
  - hostPath:
      path: /etc/kubernetes/admin.conf
    name: kubeconfig
status: {}

I am stupid and had the wrong IPs for the peers.


[iOS] Add animation for toggle TimetableSheet and TimetableList

Idea Description

Currently, no animation for that action.
Please add animation for that 🙏🏼

I think fade animation may be useful

Reference images and links

🙋

Thanks! Assigned 👍


[FEATURE][QUESTION] AspNetCore server, choose port range and strategy for the host

Hello,
As i am trying to debug distrubed lock / cluster feature, i am trying to run the exact same csproj by running either :

Multiple dotnet run in multiple host
It could also be multiple Services/Systemd running on the same host
Vs2019 > Sln Explorer > right click > Debug > Start new instance
A single F5 would be amazing

The main issue here is that, i could not find a way in the Kestrel/Listen/Http(s)Options to handle a Range of port or a PortSelectorStrategy (Kinda like the ReconnectBackoff of signalr client)
Describe the solution you'd like
Idea 1
In launchSettings.json / "applicationUrl": "http://localhost:5000;https://localhost:5001"
it's probably a bad design but it gives a small idea :
"applicationUrlBackOff":
  [
    "http://localhost:5000;https://localhost:5001",
    "http://localhost:5002;https://localhost:5003"
    "http://localhost:5004"
  ]

The idea here is that

it will first try to bind http:5000+https:5001
if at least one fail, it tries to bind to http:5002+https:5003
if at least one fail, it tries to bind to http:5004
Then classic fail

Additional context
Why ?
Because when running "Micro-service" this part is handled by an orchestrator for you like Fabric / Aks / Local Kub / ....
The issue is that when you try to debug it on a computer you have the choise to either :

dotnet publish + run it (no debug)
multiple dotnet run + injecting Console Args to attempt to override configuration (not easy)
Both scenario means that you often give up on the IDE Debbugger
You can also use the ::0 port binding but then it's totally random (not always easy for complex scenario when you need to perform incoming HttpClient request (you now needs "service discovery" locally)
Antoher possibility is to add a Huge Try/Catch arround the CreateHostBuilder/build/Start/Run and manually attempt the Fallback

Idea 2 :
In combination with the previous idea (or not, could work for console app too):
This idea is to press F5 only once in order to run + Attach Debugger the same project n times
For example it could be an integer in the launchSettings.json like :
"instanceCount" : 3
It would allow an easy way to debug a small "distributed/cluster" like application (See Idea 1)
Additionnal info
Here is a very fast draft i made in order to do that :
Pretty sure it's full of bug and weird scenario, still gives an idea ;)
using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace Foo
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var urlFallback = new UrlFallbackOptions
            {
                UrlsFallbacks = new[]
                {
                    ListeningUrls.Default,
                    new ListeningUrls { Urls = new []{ "http://localhost:5002", "https://localhost:5003" } }
                }
            };

            CreateWebHostBuilderWithFallback(args, urlFallback);
        }

        public static void CreateWebHostBuilderWithFallback(string[] args, UrlFallbackOptions urlFallbackOptions)
        {
            for (var i = 0; i < urlFallbackOptions.UrlsFallbacks.Length; i++)
            {
                try
                {
                    CreateWebHostBuilder(args, urlFallbackOptions.UrlsFallbacks[i]).Build().Run();
                    break;
                }
                catch
                {
                    if (i == urlFallbackOptions.UrlsFallbacks.Length - 1)
                    {
                        throw new Exception("you dead");
                    }
                }
            }
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args, ListeningUrls listeningUrls) =>
            WebHost.CreateDefaultBuilder(args)
                .UseUrls(listeningUrls.Urls)
                .UseStartup<Startup>();
    }

    public class UrlFallbackOptions
    {
        public ListeningUrls[] UrlsFallbacks { get; set; } = new[] { ListeningUrls.Default };
    }

    public class ListeningUrls
    {
        public static readonly string[] DefaultUrls = new[] { "http://localhost:5000", "https://localhost:5001" };

        public static readonly ListeningUrls Default = new ListeningUrls { Urls = DefaultUrls };

        public string[] Urls { get; set; } = DefaultUrls;
    }
}

As you can see the code is still netcoreapp2.2, i wonder if it's easier now with the double stack of IHostBuilder containing IWebHostBuilder

This is a pretty major feature and I don't think we plan to add such a thing to Kestrel. There are some options available such as wrapping the IServer. We also support binding to port 0 which will select any free port and the actual chosen port will be available on the IServerAddressesFeature in the server features collection. You can access that collection via the IApplicationBuilder interface in your Startup.Configure method.

Yep, it's a major one, i do understand ;)
I also use the binding to port 0 port resolution + IServerAddressesFeature in order to run E2E / IntegrationTest.
I just asked to know if it was planned or could have been planned.
The main "issue" i'm trying to solve is the fact that i have to attach multiple times the same "Host" to the same instance of Vs or VsCode, and so far it's either a hack, like the bind to 0 (not really optimal but kind of do the job)
I was just curious about such a feature (a proper "Cluster" notion)
Thx for your time ;)

It's certainly a viable feature to add to a server, but I closed it primarily because to be honest I don't see us being able to spend the time to do it. We could backlog it, but that wouldn't be particularly honest because I think it would just sit there never getting pulled up :).

i have to attach multiple times the same "Host" to the same instance of Vs or VsCode, and so far it's either a hack, like the bind to 0 (not really optimal but kind of do the job)

I'm not sure I fully understand what you mean here by "Host" or attaching to VS/VSCode. Are you trying to run multiple instances of the same app?

Don't worry, i'm totally fine with it closed, as said i was primarily looking for info

I'm not sure I fully understand what you mean here by "Host" or attaching to VS/VSCode. Are you trying to run multiple instances of the same app?

Yup the exact same bit with "n" instance, like a "distributed service"
I think when i opened the issue i was trying to debug a custom Polly policy trying to get a DistributedLock over a BlobStorage
The consuming app need to be ran multiple time and multiple kill / restart to see how healthcheck behave, who retry and when etc ....
Tested code is in a classlib so it felt weird to just create a new (almost) empty host project (dotnet new webapi)
And now ... i even wonder how Vs would react if i kill one the instance like ... would it kill all debugger etc ...
i think i'll just create an empty host next time and use multiple startup project

It seems like this might be a useful suggestion for VS rather than trying to hack around it. You can do this today as you note in your original post, but it's a little complicated. Might be a good suggestion to propose to VS to add a feature for this (though I don't know exactly what that would look like).

I think it would probably make sense as part of launchSettings.json as the idea 2 suggest but it would required that other template have something equivalent
it's only part of web "things" for now
also i posted here because running instances ends up being linked to port binding
the only way possible then is ... either using 0 or have a fallback list policy (kinda like the signalr reconnect policy)
this still leaves a question here is you need specific port but it's really not much important i think
also i'm not sure where to raise the idea for Vs, feedback hub only ?


Incomplete SettingsSchema binding

Fractal uses Settings::list_schemas() but warning: use of deprecated item 'gio::Settings::list_schemas' so I looked into replacing it. The C docs tell me to use g_settings_schema_source_list_schemas() but I couldn’t find it in the Rust bindings.

GSettingsSchemaSource is simply not bound yet, see Gir.toml.

The documentation of that functions says Do not call this function from normal programs. This is designed for use by database editors, commandline tools, etc.
So maybe this is also not the way to go?

Nonetheless, the bindings are added by this PR https://github.com/gtk-rs/gio/pull/121

GSettingsSchemaSource is simply not bound yet, see Gir.toml.

Ha, I got mislead and missed the “Source” part of it. I guess that should have been part of #74 then.

The documentation of that functions says Do not call this function from normal programs. This is designed for use by database editors, commandline tools, etc.
So maybe this is also not the way to go?

Damnit, you're right. What’s one supposed to do when something is deprecated but then they are told not to use the replacement? :-/

Thanks for the quick binding addition! I moved the discussion about Fractal’s code to #gnome-hackers and I’m going to use lookup() (which is part of the newly added binding, thanks again).


feat: use u128 for serde to avoid excess length info

This PR uses u128 for serialization instead of bare bytes because for serializers like bincode, it will add extra 8 bytes of length info for byte sequence, which, in this case, is unnecessary.

I'd rather prefer the binary compatibility with https://crates.io/crates/uuid in the serialized form. I'm also concerned that u128 is not natively supported by many serialization schemes.

I'd rather prefer the binary compatibility with https://crates.io/crates/uuid in the serialized form. I'm also concerned that u128 is not natively supported by many serialization schemes.

I see. What about an opt-in helper with #[serde(with = "module")]?

You can do that yourself, can't you?
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
struct MyEntity {
    #[serde(with = "serde_uuid7")]
    id: uuid7::Uuid,
    value: f64,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let value = MyEntity {
        id: uuid7::uuid7(),
        value: 42.0,
    };
    println!("{:?}", value);

    let encoded = bincode::serialize(&value)?;
    println!("{:?}", encoded);

    let decoded: MyEntity = bincode::deserialize(&encoded[..])?;
    println!("{:?}", decoded);

    Ok(())
}

mod serde_uuid7 {
    use serde::{de, Deserializer, Serializer};
    use std::fmt;

    pub fn serialize<S: Serializer>(v: &uuid7::Uuid, s: S) -> Result<S::Ok, S::Error> {
        s.serialize_u128(u128::from(*v))
    }

    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<uuid7::Uuid, D::Error> {
        d.deserialize_u128(VisitorImpl)
    }

    struct VisitorImpl;

    impl<'de> de::Visitor<'de> for VisitorImpl {
        type Value = uuid7::Uuid;

        fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(formatter, "a UUID representation")
        }

        fn visit_u128<E: de::Error>(self, value: u128) -> Result<Self::Value, E> {
            Ok(Self::Value::from(value))
        }
    }
}

Yeah I think this will work too.