Add gem rubocop-thread_safety

This PR is to improve thread safety of our code using the gem rubocop-thread_safety. This is preparation for switching the server from Unicorn to Puma, which runs multiple threads.
To get a standalone report, after installing the gem, run this command locally:
rubocop -r rubocop-thread_safety --only ThreadSafety,Style/GlobalVars,Style/ClassVars,Style/MutableConstant

Here's the report I got on our current codebase on main. Not bad:
app/classes/api2.rb:132:3: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
  class_attribute :initializers
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app/classes/api2.rb:147:3: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
  class_attribute :model, :table, :high_detail_includes, :low_detail_includes, ...
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

[x] fixed

app/classes/auto_complete.rb:17:3: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
  class_attribute :limit
  ^^^^^^^^^^^^^^^^^^^^^^

[x] fixed

app/classes/report/base.rb:8:5: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
    class_attribute :default_encoding
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app/classes/report/base.rb:9:5: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
    class_attribute :mime_type
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
app/classes/report/base.rb:10:5: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
    class_attribute :extension
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
app/classes/report/base.rb:11:5: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
    class_attribute :header
    ^^^^^^^^^^^^^^^^^^^^^^^
app/classes/report/base_table.rb:8:5: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
    class_attribute :separator
    ^^^^^^^^^^^^^^^^^^^^^^^^^^

[x] fixed

app/classes/robots.rb:13:54: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      populate_allowed_robot_actions unless defined?(@allowed_robot_actions)
                                                     ^^^^^^^^^^^^^^^^^^^^^^
app/classes/robots.rb:16:7: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @allowed_robot_actions["#{args[:controller]}/#{args[:action]}"]
      ^^^^^^^^^^^^^^^^^^^^^^
app/classes/robots.rb:21:7: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @allowed_robot_actions = parse_robots_dot_text(file)
      ^^^^^^^^^^^^^^^^^^^^^^

[ ] fixed

app/classes/token.rb:24:5: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    @crypt ||= ActiveSupport::MessageEncryptor.new(
    ^^^^^^

[ ] fixed

app/controllers/application_controller.rb:1323:7: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @index_subaction_param_keys ||= []
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
app/controllers/application_controller.rb:1327:7: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @index_subaction_dispatch_table ||= {}
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

[ ] fixed

app/extensions/symbol_extensions.rb:22:5: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    @raise_errors = turn_on
    ^^^^^^^^^^^^^
app/extensions/symbol_extensions.rb:26:5: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    @raise_errors
    ^^^^^^^^^^^^^

[ ] fixed

app/models/abstract_model.rb:641:3: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
  class_attribute :autolog_events
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

[ ] fixed

app/models/language_exporter.rb:40:7: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @locales_path = "config/locales" if @locales_path.nil?
      ^^^^^^^^^^^^^
app/models/language_exporter.rb:40:43: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @locales_path = "config/locales" if @locales_path.nil?
                                          ^^^^^^^^^^^^^
app/models/language_exporter.rb:41:26: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      "#{::Rails.root}/#{@locales_path}"
                         ^^^^^^^^^^^^^
app/models/language_exporter.rb:45:7: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @locales_path = path
      ^^^^^^^^^^^^^

[ ] fixed

app/models/naming.rb:75:19: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    naming.user = @user
                  ^^^^^

[x] fixed

app/models/query_record.rb:34:29: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    return unless !defined?(@last_cleanup) ||
                            ^^^^^^^^^^^^^
app/models/query_record.rb:35:20: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
                  (@last_cleanup < 5.minutes.ago) ||
                   ^^^^^^^^^^^^^
app/models/query_record.rb:40:5: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    @last_cleanup = Time.zone.now
    ^^^^^^^^^^^^^

[ ] fixed

app/models/queued_email.rb:161:3: C: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
  cattr_accessor(:queue, default: false)
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

[ ] fixed

app/models/vote.rb:81:17: C: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    vote.user = @user

[x] fixed

coverage: 94.532%. remained the same
when pulling d36833f5d6f389bac8c581db0ed9222bd72a9939 on nimmo-thread-safety
into<PHONE_NUMBER>540b6a6ed218a152aaaf314c58aff5 on main.

@mo-nathan if you know anything about safer workarounds for either of these usages that are flagged by the gem, suggestions welcome. Our violations (which may or may not potentially cause problems in production with Puma, I don't know) boil down to two types:

"mutating class and module attributes"
"instance variables in class methods"

@nimmolo You've probably already seen this, but just in case: Correcting code for thread-safety

Here's the report I got on our current codebase on main. Not bad:

Unfortunately, it's somewhat worse. Running
rubocop -r rubocop-thread_safety --only ThreadSafety,Style/GlobalVars,Style/ClassVars,Style/MutableConstant

uses the configuration of .rubocop.yml, which in turn inherits from .rubocop_todo.yml, (see https://docs.rubocop.org/rubocop/configuration.html#automatically-generated-configuration), which Exclude's many offenses from the report.
The report at the top has about 25 offenses.
The actual number is
1087 files inspected, 95 offenses detected

Here's what I'll do now to get an accurate count of threading issue in this branch (and on main) and to have the rubocop command above work properly for present purposes.

[ ] Create a new branch

[ ] Update rubocop (which may fix some false positives or negatives for threading issues)
[ ] Regenerate the .rubocop_todo.yml
[ ]  Edit .rubocop_todo.yml to remove exclusions of thread-related cops

[ ] Create a PR. WARNING There will be at least 70 new Codeclimate offenses (because editing .rubocop_todo.yml unveils some offense which that file hides)
[ ] Merge the new branch into main, ignoring the Codeclimate warning.
[ ] Merge main into this branch (nimmo-thread-safety) so that:

This branch includes @pellaea's recent fixes of of thread issues;
.rubocop_todo.yml no longer hides threading offenses
rubocop -r rubocop-thread_safety --only ThreadSafety,Style/GlobalVars,Style/ClassVars,Style/MutableConstant works OK for present purposes.

[ ] Regenerate the threading offenses report and paste it into this branch.

RuboCop Inspection Report
Updated 2023-02-21 11:54 PSR
1088 files inspected, 87 offenses detected:
app/classes/content_filter.rb - (1 offense)

[ ] Line # 45 - convention: Style/ClassVars: Replace class var @@filters with a class instance var.
    @@filters ||= [

app/classes/ip_stats.rb - (4 offenses)

[ ] Line # 141 - convention: Style/ClassVars: Replace class var @@blocked_ips_time with a class instance var.
      @@blocked_ips_time = nil

[ ] Line # 168 - convention: Style/ClassVars: Replace class var @@blocked_ips with a class instance var.
      @@blocked_ips = parse_ip_list(file1)

[ ] Line # 169 - convention: Style/ClassVars: Replace class var @@okay_ips with a class instance var.
      @@okay_ips = parse_ip_list(file2)

[ ] Line # 170 - convention: Style/ClassVars: Replace class var @@blocked_ips_time with a class instance var.
      @@blocked_ips_time = [File.mtime(file1), File.mtime(file2)].max

app/classes/robots.rb - (3 offenses)

[ ] Line # 13 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      populate_allowed_robot_actions unless defined?(@allowed_robot_actions)

[ ] Line # 16 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @allowed_robot_actions["#{args[:controller]}/#{args[:action]}"]

[ ] Line # 21 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @allowed_robot_actions = parse_robots_dot_text(file)

app/classes/run_level.rb - (3 offenses)

[ ] Line # 6 - convention: Style/ClassVars: Replace class var @@runlevel with a class instance var.
  @@runlevel = :normal

[ ] Line # 9 - convention: Style/ClassVars: Replace class var @@runlevel with a class instance var.
    @@runlevel = :normal

[ ] Line # 13 - convention: Style/ClassVars: Replace class var @@runlevel with a class instance var.
    @@runlevel = :silent

app/classes/textile.rb - (20 offenses)

[ ] Line # 32 - convention: Style/ClassVars: Replace class var @@name_lookup with a class instance var.
  @@name_lookup     = {}

[ ] Line # 33 - convention: Style/ClassVars: Replace class var @@last_species with a class instance var.
  @@last_species    = nil

[ ] Line # 34 - convention: Style/ClassVars: Replace class var @@last_subspecies with a class instance var.
  @@last_subspecies = nil

[ ] Line # 35 - convention: Style/ClassVars: Replace class var @@last_variety with a class instance var.
  @@last_variety    = nil

[ ] Line # 151 - convention: Style/ClassVars: Replace class var @@name_lookup with a class instance var.
    @@name_lookup ||= {}

[ ] Line # 155 - convention: Style/ClassVars: Replace class var @@last_species with a class instance var.
      @@last_species    = name

[ ] Line # 156 - convention: Style/ClassVars: Replace class var @@last_subspecies with a class instance var.
      @@last_subspecies = nil

[ ] Line # 157 - convention: Style/ClassVars: Replace class var @@last_variety with a class instance var.
      @@last_variety    = nil

[ ] Line # 159 - convention: Style/ClassVars: Replace class var @@last_species with a class instance var.
      @@last_species    = name.sub(/ ssp\. .*/, "")

[ ] Line # 160 - convention: Style/ClassVars: Replace class var @@last_subspecies with a class instance var.
      @@last_subspecies = name

[ ] Line # 161 - convention: Style/ClassVars: Replace class var @@last_variety with a class instance var.
      @@last_variety    = nil

[ ] Line # 163 - convention: Style/ClassVars: Replace class var @@last_species with a class instance var.
      @@last_species    = name.sub(/ (ssp|var)\. .*/, "")

[ ] Line # 164 - convention: Style/ClassVars: Replace class var @@last_subspecies with a class instance var.
      @@last_subspecies = name.sub(/ var\. .*/, "")

[ ] Line # 165 - convention: Style/ClassVars: Replace class var @@last_variety with a class instance var.
      @@last_variety    = name

[ ] Line # 188 - convention: Style/ClassVars: Replace class var @@name_lookup with a class instance var.
    @@name_lookup ||= {}

[ ] Line # 194 - convention: Style/ClassVars: Replace class var @@name_lookup with a class instance var.
    @@name_lookup     = {}

[ ] Line # 195 - convention: Style/ClassVars: Replace class var @@last_species with a class instance var.
    @@last_species    = nil

[ ] Line # 196 - convention: Style/ClassVars: Replace class var @@last_subspecies with a class instance var.
    @@last_subspecies = nil

[ ] Line # 197 - convention: Style/ClassVars: Replace class var @@last_variety with a class instance var.
    @@last_variety    = nil

[ ] Line # 252 - convention: Style/ClassVars: Replace class var @@name_lookup with a class instance var.
    @@name_lookup ||= {}

app/classes/token.rb - (1 offense)

[ ] Line # 24 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    @crypt ||= ActiveSupport::MessageEncryptor.new(

app/controllers/application_controller.rb - (2 offenses)

[ ] Line # 1323 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @index_subaction_param_keys ||= []

[ ] Line # 1327 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @index_subaction_dispatch_table ||= {}

app/extensions/symbol_extensions.rb - (4 offenses)

[ ] Line # 22 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    @raise_errors = turn_on

[ ] Line # 26 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    @raise_errors

[ ] Line # 45 - convention: Style/ClassVars: Replace class var @@missing_tags with a class instance var.
    @@missing_tags = [] unless defined?(@@missing_tags)

[ ] Line # 51 - convention: Style/ClassVars: Replace class var @@missing_tags with a class instance var.
    @@missing_tags = tags

app/models/abstract_model.rb - (1 offense)

[ ] Line # 641 - convention: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
  class_attribute :autolog_events

app/models/language.rb - (1 offense)

[ ] Line # 126 - convention: Style/ClassVars: Replace class var @@last_update with a class instance var.
  @@last_update = 1.minute.ago

app/models/language_exporter.rb - (4 offenses)

[ ] Line # 40 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @locales_path = "config/locales" if @locales_path.nil?

[ ] Line # 40 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @locales_path = "config/locales" if @locales_path.nil?

[ ] Line # 41 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      "#{::Rails.root}/#{@locales_path}"

[ ] Line # 45 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
      @locales_path = path

app/models/language_tracking.rb - (5 offenses)

[ ] Line # 35 - convention: Style/ClassVars: Replace class var @@tags_used with a class instance var.
  @@tags_used = nil

[ ] Line # 36 - convention: Style/ClassVars: Replace class var @@last_clean with a class instance var.
  @@last_clean = nil

[ ] Line # 43 - convention: Style/ClassVars: Replace class var @@tags_used with a class instance var.
    @@tags_used = {}

[ ] Line # 52 - convention: Style/ClassVars: Replace class var @@tags_used with a class instance var.
    @@tags_used = nil

[ ] Line # 105 - convention: Style/ClassVars: Replace class var @@last_clean with a class instance var.
    @@last_clean = Time.zone.now

app/models/location.rb - (3 offenses)

[ ] Line # 320 - convention: Style/ClassVars: Replace class var @@names_for_unknown with a class instance var.
    @@names_for_unknown ||= official_unknown

[ ] Line # 526 - convention: Style/ClassVars: Replace class var @@location_cache with a class instance var.
  @@location_cache = nil

[ ] Line # 533 - convention: Style/ClassVars: Replace class var @@location_cache with a class instance var.
    @@location_cache ||= (

app/models/query_record.rb - (3 offenses)

[ ] Line # 34 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    return unless !defined?(@last_cleanup) ||

[ ] Line # 35 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
                  (@last_cleanup < 5.minutes.ago) ||

[ ] Line # 40 - convention: ThreadSafety/InstanceVariableInClassMethod: Avoid instance variables in class methods.
    @last_cleanup = Time.zone.now

app/models/queued_email.rb - (2 offenses)

[ ] Line # 144 - convention: Style/ClassVars: Replace class var @@all_flavors with a class instance var.
      @@all_flavors = []

[ ] Line # 161 - convention: ThreadSafety/ClassAndModuleAttributes: Avoid mutating class and module attributes.
  cattr_accessor(:queue, default: false)

app/models/user.rb - (6 offenses)

[ ] Line # 376 - convention: Style/ClassVars: Replace class var @@user with a class instance var.
    @@user = nil unless defined?(@@user)

[ ] Line # 385 - convention: Style/ClassVars: Replace class var @@user with a class instance var.
    @@user = nil unless defined?(@@user)

[ ] Line # 392 - convention: Style/ClassVars: Replace class var @@location_format with a class instance var.
    @@location_format = val ? val.location_format : "postal"

[ ] Line # 393 - convention: Style/ClassVars: Replace class var @@user with a class instance var.
    @@user = val

[ ] Line # 401 - convention: Style/ClassVars: Replace class var @@location_format with a class instance var.
    @@location_format = "postal" unless defined?(@@location_format)

[ ] Line # 407 - convention: Style/ClassVars: Replace class var @@location_format with a class instance var.
    @@location_format = val

app/models/user_group.rb - (6 offenses)

[ ] Line # 88 - convention: Style/ClassVars: Replace class var @@all_users with a class instance var.
    @@all_users ||= get_or_construct_user("all users")

[ ] Line # 94 - convention: Style/ClassVars: Replace class var @@one_users with a class instance var.
    @@one_users ||= {}

[ ] Line # 100 - convention: Style/ClassVars: Replace class var @@reviewers with a class instance var.
    @@reviewers ||= get_or_construct_user("reviewers")

[ ] Line # 106 - convention: Style/ClassVars: Replace class var @@all_users with a class instance var.
    @@all_users = @@one_users = @@reviewers = nil

[ ] Line # 106 - convention: Style/ClassVars: Replace class var @@one_users with a class instance var.
    @@all_users = @@one_users = @@reviewers = nil

[ ] Line # 106 - convention: Style/ClassVars: Replace class var @@reviewers with a class instance var.
    @@all_users = @@one_users = @@reviewers = nil

test/controllers/locations_controller_test.rb - (4 offenses)

[ ] Line # 9 - convention: Style/ClassVars: Replace class var @@emails with a class instance var.
    @@emails ||= []

[ ] Line # 18 - convention: Style/ClassVars: Replace class var @@emails with a class instance var.
    @@emails = []

[ ] Line # 25 - convention: Style/ClassVars: Replace class var @@emails with a class instance var.
    @@emails = []

[ ] Line # 33 - convention: Style/ClassVars: Replace class var @@emails with a class instance var.
    @@emails = []

test/controllers/names_controller_test.rb - (4 offenses)

[ ] Line # 11 - convention: Style/ClassVars: Replace class var @@emails with a class instance var.
    @@emails ||= []

[ ] Line # 20 - convention: Style/ClassVars: Replace class var @@emails with a class instance var.
    @@emails = []

[ ] Line # 27 - convention: Style/ClassVars: Replace class var @@emails with a class instance var.
    @@emails = []

[ ] Line # 35 - convention: Style/ClassVars: Replace class var @@emails with a class instance var.
    @@emails = []

test/general_extensions.rb - (1 offense)

[ ] Line # 289 - convention: Style/ClassVars: Replace class var @@fixture_labels with a class instance var.
  @@fixture_labels = {}

test/language_extensions.rb - (7 offenses)

[ ] Line # 10 - convention: Style/ClassVars: Replace class var @@verbose_messages with a class instance var.
  @@verbose_messages = []

[ ] Line # 13 - convention: Style/ClassVars: Replace class var @@localization_files with a class instance var.
    @@localization_files = {}

[ ] Line # 14 - convention: Style/ClassVars: Replace class var @@export_files with a class instance var.
    @@export_files = {}

[ ] Line # 18 - convention: Style/ClassVars: Replace class var @@localization_files with a class instance var.
    @@localization_files = nil

[ ] Line # 19 - convention: Style/ClassVars: Replace class var @@export_files with a class instance var.
    @@export_files = nil

[ ] Line # 23 - convention: Style/ClassVars: Replace class var @@last_update with a class instance var.
    @@last_update = val

[ ] Line # 27 - convention: Style/ClassVars: Replace class var @@verbose_messages with a class instance var.
    @@verbose_messages = []

test/test_helper.rb - (2 offenses)

[ ] Line # 153 - convention: Style/ClassVars: Replace class var @@times with a class instance var.
      @@times = {} unless defined?(@@times)

[ ] Line # 173 - convention: Style/ClassVars: Replace class var @@cleared_logs with a class instance var.
      @@cleared_logs = true

Yes it should include everything current, except the ones Jason fixed.
It's just the current output of the RuboCop command that you started with, output in .md format (and I tweaked the format a bit to use checkboxes.) You can read more about the format options at https://docs.rubocop.org/rubocop/formatters.html.

Although class instance variables are better than class variables, they still may be problematic for thread safety. See https://bearmetal.eu/theden/how-do-i-know-whether-my-rails-app-is-thread-safe-or-not/.

@JoeCohen - did you notice that it's flagging your @index_subaction ivars in app/controllers/application_controller.rb? How should we handle that?
Or... are these OK because they're only ever instantiated in a controller that inherits from this, and controller ivars are thread safe by definition. Or... is it very much the opposite, and the ivar "belongs" to ApplicationController and is getting mutated unpredictably?

@nimmolo I hadn't noticed that. I will have to think it over.
Perhaps @mo-nathan has some thoughts; he pointed the way to this refactor.
Another issue may be that these ivars use the non-atomic operator ||=. See here, particularly

Don’t memoize to class variables or class instance variables. If you need to memoize something on the class level, use thread local variables (Thread.current[:baz]) instead. Be aware, though, that it is still kind of a global variable. So while it’s thread-safe, it still might not be good coding practice.

Should we merge this so we can use it while working on thread safety?


postBuild for both Python 2 and Python 3

I have created a build with Python 2 kernel as advised in docs (python-2.7 in runtime.txt).
However it seems that python setup.py install in postBuild has been run in Python 3 (which is good as I have Python 3 notebooks too) but not in Python 2 (my package is not installed).
The notebooks are here: https://mybinder.org/v2/gh/Neuroinflab/PyMICE/tutorials?filepath=tutorial
I have also tried to activate python2 environment in the postBuild:
python setup.py install
source python2/activate
python setup.py install

but the build crashes too often (requirement download problem I guess) to figure out the solution efficiently.

I have solved the issue with the following postBuild:
python setup.py install
python2 setup.py install

I think it might be helpful to add postBuild scenario to the example.

@choldgraf I have a similar issue.
My repo is here: https://github.com/timothyb0912/check-yourself/tree/ce264_march10th_2020
I can launch binder with this repo and branch, but the python2 environment never gets built despite the existence of the runtime.txt file with python-2.7 in it.
Currently it causes annoying issues when using the notebooks because I get repeating messages about the notebook not being trusted and the python 3 kernel being used for a python 2 notebook.
I can confirm that the notebook I've save was saved with python2 kernel. The easiest way is probably from the jupytext metadata: https://github.com/timothyb0912/check-yourself/blob/ce264_march10th_2020/notebooks/_14-tb-CE264-Checking-Demo.py#L11
Can you advise on what to do?

Hmm - on this one I would try asking around in the community forum : discourse.jupyter.org ...I think that you might get some more input from folks there, since the issues in these example repos aren't checked much


Bump backport-action to v1 major release

Description of your changes

This pull requests bumps the backport-action to its latest version, and adjusts the workflow accordingly.
The v1 release of this backport-action has a few improvements:

faster, it no longer requires fetch-depth 0 checkouts and it fetches only the necessary commits
major release tag moves along with patches (SemVer)
it no longer requires any inputs by default

Note that the repo moved from zeebe-io to korthout. See releases notes v1.0.0.
I have:

[x] Read and followed Crossplane's contribution process.
[ ] Run make reviewable to ensure this PR is ready for review.
[ ] Added backport release-x.y labels to auto-backport this PR if necessary.

How has this code been tested

Zeebe itself has switched to this version https://github.com/camunda/zeebe/blob/main/.github/workflows/backport.yml#L30
The action is tested using https://github.com/korthout/backport-action-test

@negz Could you have a look at this?
Please note that I was unable to run make reviewable:
 make reviewable
make: *** No rule to make target `reviewable'.  Stop.

@korthout please run make submodules, it should make make reviewable available :)

Thanks @ytsarev
I ran into another issue. Could you help me out?
make reviewable
10:47:40 [ .. ] verify dependencies have expected content
all modules verified
10:47:42 [ OK ] go modules dependencies verified
10:47:42 [ .. ] go generate darwin_amd64
10:47:48 [ OK ] go generate darwin_amd64
10:47:48 [ .. ] go mod tidy
10:47:48 [ OK ] go mod tidy
10:47:48 [ .. ] verify dependencies have expected content
all modules verified
10:47:50 [ OK ] go modules dependencies verified
10:47:51 [ .. ] golangci-lint
WARN [runner] Can't run linter goanalysis_metalinter: bodyclose: failed prerequisites<EMAIL_ADDRESS>analysis skipped: errors in package: [/Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/groupversion_info.go:24:2: could not import k8s.io/apimachinery/pkg/runtime/schema (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/k8s.io/apimachinery@v0.25.3/pkg/runtime/schema/generated.pb.go:23:6: could not import fmt (/usr/local/Cellar/go/1.19.4/libexec/src/fmt/errors.go:7:8: could not import errors (/usr/local/Cellar/go/1.19.4/libexec/src/errors/wrap.go:8:2: could not import internal/reflectlite (/usr/local/Cellar/go/1.19.4/libexec/src/internal/reflectlite/swapper.go:8:2: could not import internal/goarch (-: could not load export data: cannot import "internal/goarch" (unknown iexport format version 2), export data is newer version - update tool))))) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/groupversion_info.go:25:2: could not import sigs.k8s.io/controller-runtime/pkg/scheme (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/sigs.k8s.io/controller-runtime@v0.12.0/pkg/scheme/scheme.go:58:9: could not import k8s.io/apimachinery/pkg/apis/meta/v1 (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/k8s.io/apimachinery@v0.25.3/pkg/apis/meta/v1/controller_ref.go:20:2: could not import k8s.io/apimachinery/pkg/runtime/schema (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/k8s.io/apimachinery@v0.25.3/pkg/runtime/schema/generated.pb.go:23:6: could not import fmt (/usr/local/Cellar/go/1.19.4/libexec/src/fmt/errors.go:7:8: could not import errors (/usr/local/Cellar/go/1.19.4/libexec/src/errors/wrap.go:8:2: could not import internal/reflectlite (/usr/local/Cellar/go/1.19.4/libexec/src/internal/reflectlite/swapper.go:8:2: could not import internal/goarch (-: could not load export data: cannot import "internal/goarch" (unknown iexport format version 2), export data is newer version - update tool))))))) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/mytype_types.go:20:2: could not import reflect (/usr/local/Cellar/go/1.19.4/libexec/src/reflect/abi.go:8:2: could not import internal/abi (/usr/local/Cellar/go/1.19.4/libexec/src/internal/abi/abi.go:8:2: could not import internal/goarch (-: could not load export data: cannot import "internal/goarch" (unknown iexport format version 2), export data is newer version - update tool))) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/mytype_types.go:22:9: could not import k8s.io/apimachinery/pkg/apis/meta/v1 (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/k8s.io/apimachinery@v0.25.3/pkg/apis/meta/v1/controller_ref.go:20:2: could not import k8s.io/apimachinery/pkg/runtime/schema (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/k8s.io/apimachinery@v0.25.3/pkg/runtime/schema/generated.pb.go:23:6: could not import fmt (/usr/local/Cellar/go/1.19.4/libexec/src/fmt/errors.go:7:8: could not import errors (/usr/local/Cellar/go/1.19.4/libexec/src/errors/wrap.go:8:2: could not import internal/reflectlite (/usr/local/Cellar/go/1.19.4/libexec/src/internal/reflectlite/swapper.go:8:2: could not import internal/goarch (-: could not load export data: cannot import "internal/goarch" (unknown iexport format version 2), export data is newer version - update tool)))))) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/mytype_types.go:25:7: could not import github.com/crossplane/crossplane-runtime/apis/common/v1 (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/github.com/crossplane/crossplane-runtime@v0.18.0/apis/common/v1/condition.go:20:2: could not import sort (/usr/local/Cellar/go/1.19.4/libexec/src/sort/slice.go:7:8: could not import math/bits (-: could not load export data: cannot import "math/bits" (unknown iexport format version 2), export data is newer version - update tool))) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.deepcopy.go:25:10: could not import k8s.io/apimachinery/pkg/runtime (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/k8s.io/apimachinery@v0.25.3/pkg/runtime/allocator.go:20:2: could not import sync (/usr/local/Cellar/go/1.19.4/libexec/src/sync/cond.go:8:2: could not import sync/atomic (/usr/local/Cellar/go/1.19.4/libexec/src/sync/atomic/type.go:39:16: expected ']', found any))) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managedlist.go:20:17: could not import github.com/crossplane/crossplane-runtime/pkg/resource (/Users/korthout/dev/github/provider-template/.work/pkg/pkg/mod/github.com/crossplane/crossplane-runtime@v0.18.0/pkg/resource/api.go:20:2: could not import context (/usr/local/Cellar/go/1.19.4/libexec/src/context/context.go:51:2: could not import errors (/usr/local/Cellar/go/1.19.4/libexec/src/errors/wrap.go:8:2: could not import internal/reflectlite (/usr/local/Cellar/go/1.19.4/libexec/src/internal/reflectlite/swapper.go:8:2: could not import internal/goarch (-: could not load export data: cannot import "internal/goarch" (unknown iexport format version 2), export data is newer version - update tool))))) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:24:19: mg.Status.GetCondition undefined (type MyTypeStatus has no field or method GetCondition) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:29:17: mg.Spec.DeletionPolicy undefined (type MyTypeSpec has no field or method DeletionPolicy) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:34:17: mg.Spec.ProviderConfigReference undefined (type MyTypeSpec has no field or method ProviderConfigReference) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:42:17: mg.Spec.ProviderReference undefined (type MyTypeSpec has no field or method ProviderReference) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:47:17: mg.Spec.PublishConnectionDetailsTo undefined (type MyTypeSpec has no field or method PublishConnectionDetailsTo) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:52:17: mg.Spec.WriteConnectionSecretToReference undefined (type MyTypeSpec has no field or method WriteConnectionSecretToReference) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:57:12: mg.Status.SetConditions undefined (type MyTypeStatus has no field or method SetConditions) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:62:10: mg.Spec.DeletionPolicy undefined (type MyTypeSpec has no field or method DeletionPolicy) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:67:10: mg.Spec.ProviderConfigReference undefined (type MyTypeSpec has no field or method ProviderConfigReference) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:75:10: mg.Spec.ProviderReference undefined (type MyTypeSpec has no field or method ProviderReference) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:80:10: mg.Spec.PublishConnectionDetailsTo undefined (type MyTypeSpec has no field or method PublishConnectionDetailsTo) /Users/korthout/dev/github/provider-template/apis/sample/v1alpha1/zz_generated.managed.go:85:10: mg.Spec.WriteConnectionSecretToReference undefined (type MyTypeSpec has no field or method WriteConnectionSecretToReference)]]
WARN [runner] Can't run linter unused: buildir: failed to load package goarch: could not load export data: cannot import "internal/goarch" (unknown iexport format version 2), export data is newer version - update tool
ERRO Running error: buildir: failed to load package goarch: could not load export data: cannot import "internal/goarch" (unknown iexport format version 2), export data is newer version - update tool
10:47:55 [FAIL]
make[2]: *** [go.lint] Error 1
make[1]: *** [lint] Error 2
make: *** [reviewable] Error 2

I'm not so familiar with Go. It seems there's an issue with a version. I'm on go version go1.19.4 darwin/amd64.

@ytsarev It might just be a problem on my machine. Could you please run the CI workflow on these changes? As I read that file, it should also perform the lining (although with a different tool).

@korthout looks like I don't have access rights to this repo, I'll ask around

Thanks @jbw976, glad you like it. I think this is only waiting on an approving review. The CI checks have been passed successfully.

@jbw976 Is there anything I should do before this can be approved?


cloud-init is nos installed when ros install -install-type noformat

RancherOS Version: (ros os version)
1.4.1
Where are you running RancherOS? (docker-machine, AWS, GCE, baremetal, etc.)
vbox, vmware
If you partition manually the disk and after run the ros install with noformat installtype, ros ignore cloud-config passed by parameter.
`
DRIVE=/dev/sda
echo ", 500M,83,*
, 5G,83
,,83;" > /tmp/layout
sudo sfdisk "${DRIVE}" < /tmp/layout
sudo mkfs.ext4 -L RANCHER_BOOT "${DRIVE}1"
sudo mkfs.ext4 -L RANCHER_STATE "${DRIVE}2"
cat >cloud-init.yml<<EOF
#cloud-config
ssh_authorized_keys:

"ssh-rsa ${SSH_PUBLIC_KEY}"
rancher:
console: ubuntu
EOF
ros install -install-type noformat  -device /dev/sda -c cloud-init.yml --force
`
Load Rancheros on ram with a ISO
set SSH_PUBLIC_KEY variable
execute the script in the example

Expected behaviour is ros is installed and ssh key is setted and load with ubuntu console.
what really happens is rancher load from disk but ignored all the configurations of cloud-init
Tested on vbox and vmware

Wow, this should be a bug.

@segator Thank you for the bug report!
Fixed in rancher/os:ab4e0e5

backported to v1.4.2


Google optimize doesn't work

Hi im trying to implement Google Optimize to nuxt3 using partytown. I've implement script adding new plugin to nuxt3:
export default defineNuxtPlugin((nuxtApp: NuxtApp) => {
  const config = useRuntimeConfig();
  useHead({
    script: [
      {
        src: `https://www.googleoptimize.com/optimize.js?id=${config.optimizeId}`,
        async: true,
        gtm: config.gtmId,
        type: 'text/partytown',
      }
    ],
  });
});

I see that script is loading properly:
<script src="https://www.googleoptimize.com/optimize.js?id=OPT-MMSMPHJ" async="true" type="text/partytown-x" gtm="GTM-W57WWW2"></script>

you can check, that the code above is generated here: https://qa.lendi.pl/
I've also tried to set forwarding by adding this to nuxt.config:
  partytown: {
    debug: true,
    logScriptExecution: true,
    logStackTraces: true,
    forward: ['google_optimize', 'google_tag_manager',],
  }

But unfortunately my optimize experiments does not work. When I change script type from text/partytown to text/javascript everything works fine

Shouldn't the script contain type="text/partytown" Instead of type="text/partytown-x" ?


BuiltinFunction: Use a generated DAFSA instead of a generated enum

A DAFSA (deterministic acyclic finite state automaton) is essentially a trie flattened into an array, but that also uses techniques to minimize redundant nodes. This provides fast lookups while minimizing the required data size, but normally does not allow for associating data related to each word. However, by adding a count of the number of possible words from each node, it becomes possible to also use it to achieve minimal perfect hashing for the set of words (which allows going from word -> unique index as well as unique index -> word). This allows us to store a second array of data so that the DAFSA can be used as a lookup for e.g. BuiltinFunction.
Some resources:

https://en.wikipedia.org/wiki/Deterministic_acyclic_finite_state_automaton
https://web.archive.org/web/20220722224703/http://pages.pathcom.com/~vadco/dawg.html
https://citeseerx.ist.psu.edu/viewdoc/summary?doi=<IP_ADDRESS>.5272 (this is the origin of the minimal perfect hashing technique)
http://stevehanov.ca/blog/?id=115

What all is going on here:

process_builtins.py was removed in favor of a zig implementation that generates the DAFSA
The new zig implementation uses the latest .def files from the LLVM repository, so the set of builtins is different and there are some new macro definitions that are not yet supported (e.g. TARGET_BUILTIN), but otherwise the logic matches the python script wherever possible
The new zig implementation imports src/builtins/TypeDescription.zig directly so the calculated max parameter count will always be in sync

The results
Microbenchmark of lookup time:
# Does a builtin name exist?:

------------------- dafsa ------------------
            always found: 88ns per lookup
not found (random bytes): 33ns per lookup
 not found (1 char diff): 86ns per lookup
------------------- enum -------------------
            always found: 3648ns per lookup
not found (random bytes): 6310ns per lookup
 not found (1 char diff): 3604ns per lookup

dafsa is 41.5x / 191.2x / 41.9x faster

# Name -> BuiltinFunction lookup:

------------------- dafsa ------------------
            always found: 154ns per lookup
not found (random bytes): 32ns per lookup
 not found (1 char diff): 154ns per lookup
------------------- enum -------------------
            always found: 3649ns per lookup
not found (random bytes): 6317ns per lookup
 not found (1 char diff): 3649ns per lookup

dafsa is 23.7x / 197.4x / 23.7x faster

(tested with the same set of builtins in the dafsa and enum code)

Microbenchmark code
const std = @import("std");
const dafsa_ver = @import("generated_dafsa.zig");
const enum_ver = @import("generated_enum.zig");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer std.debug.assert(gpa.deinit() == .ok);
    const allocator = gpa.allocator();

    var builtins_list = std.ArrayList([]const u8).init(allocator);
    defer builtins_list.deinit();

    var contents = try std.fs.cwd().readFileAlloc(allocator, "builtins.txt", std.math.maxInt(u32));
    defer allocator.free(contents);

    var line_it = std.mem.tokenizeAny(u8, contents, "\r\n");
    while (line_it.next()) |line| {
        try builtins_list.append(line);
    }

    {
        std.debug.print("Lookup time (does name exist?):\n\n", .{});
        std.debug.print("------------------- dafsa ------------------\n", .{});
        const dafsa_found = try benchFound(builtins_list.items, dafsa_ver.exists);
        std.debug.print("            always found: {}ns per lookup\n", .{dafsa_found});
        const dafsa_random = try benchRandomBytes(dafsa_ver.exists);
        std.debug.print("not found (random bytes): {}ns per lookup\n", .{dafsa_random});
        const dafsa_modified = try benchModified(builtins_list.items, dafsa_ver.exists);
        std.debug.print(" not found (1 char diff): {}ns per lookup\n", .{dafsa_modified});
        std.debug.print("------------------- enum -------------------\n", .{});
        const enum_found = try benchFound(builtins_list.items, enum_ver.exists);
        std.debug.print("            always found: {}ns per lookup\n", .{enum_found});
        const enum_random = try benchRandomBytes(enum_ver.exists);
        std.debug.print("not found (random bytes): {}ns per lookup\n", .{enum_random});
        const enum_modified = try benchModified(builtins_list.items, enum_ver.exists);
        std.debug.print(" not found (1 char diff): {}ns per lookup\n", .{enum_modified});

        std.debug.print("\ndafsa is {d:.1}x / {d:.1}x / {d:.1}x faster\n", .{
            @as(f64, @floatFromInt(enum_found)) / @as(f64, @floatFromInt(dafsa_found)),
            @as(f64, @floatFromInt(enum_random)) / @as(f64, @floatFromInt(dafsa_random)),
            @as(f64, @floatFromInt(enum_modified)) / @as(f64, @floatFromInt(dafsa_modified)),
        });
    }
    {
        std.debug.print("\n\nLookup time (name -> BuiltinFunction):\n\n", .{});
        std.debug.print("------------------- dafsa ------------------\n", .{});
        const dafsa_found = try benchFound(builtins_list.items, dafsa_ver.fromName);
        std.debug.print("            always found: {}ns per lookup\n", .{dafsa_found});
        const dafsa_random = try benchRandomBytes(dafsa_ver.fromName);
        std.debug.print("not found (random bytes): {}ns per lookup\n", .{dafsa_random});
        const dafsa_modified = try benchModified(builtins_list.items, dafsa_ver.fromName);
        std.debug.print(" not found (1 char diff): {}ns per lookup\n", .{dafsa_modified});
        std.debug.print("------------------- enum -------------------\n", .{});
        const enum_found = try benchFound(builtins_list.items, enum_ver.fromName);
        std.debug.print("            always found: {}ns per lookup\n", .{enum_found});
        const enum_random = try benchRandomBytes(enum_ver.fromName);
        std.debug.print("not found (random bytes): {}ns per lookup\n", .{enum_random});
        const enum_modified = try benchModified(builtins_list.items, enum_ver.fromName);
        std.debug.print(" not found (1 char diff): {}ns per lookup\n", .{enum_modified});

        std.debug.print("\ndafsa is {d:.1}x / {d:.1}x / {d:.1}x faster\n", .{
            @as(f64, @floatFromInt(enum_found)) / @as(f64, @floatFromInt(dafsa_found)),
            @as(f64, @floatFromInt(enum_random)) / @as(f64, @floatFromInt(dafsa_random)),
            @as(f64, @floatFromInt(enum_modified)) / @as(f64, @floatFromInt(dafsa_modified)),
        });
    }
}

fn benchFound(builtins: []const []const u8, func: anytype) !u64 {
    var prng = std.rand.DefaultPrng.init(0);
    const rand = prng.random();

    var timer = try std.time.Timer.start();

    const iterations = 1_000_000;
    for (0..iterations) |_| {
        const name = builtins[rand.intRangeLessThanBiased(usize, 0, builtins.len)];
        var result = func(name);
        std.mem.doNotOptimizeAway(&result);
    }

    const elapsed = timer.read();

    return elapsed / iterations;
}

fn benchRandomBytes(func: anytype) !u64 {
    var prng = std.rand.DefaultPrng.init(0);
    const rand = prng.random();

    var timer = try std.time.Timer.start();

    const iterations = 1_000_000;
    for (0..iterations) |_| {
        var name_buf: [128]u8 = undefined;
        const name_len = rand.intRangeAtMostBiased(usize, 1, name_buf.len);
        var name = name_buf[0..name_len];
        rand.bytes(name);
        var result = func(name);
        std.mem.doNotOptimizeAway(&result);
    }

    const elapsed = timer.read();

    return elapsed / iterations;
}

fn benchModified(builtins: []const []const u8, func: anytype) !u64 {
    var prng = std.rand.DefaultPrng.init(0);
    const rand = prng.random();

    var timer = try std.time.Timer.start();

    const iterations = 1_000_000;
    for (0..iterations) |_| {
        const name = builtins[rand.intRangeLessThanBiased(usize, 0, builtins.len)];
        var name_buf: [128]u8 = undefined;
        var modified_name = name_buf[0..name.len];
        @memcpy(modified_name, name);
        modified_name[rand.intRangeLessThanBiased(usize, 0, modified_name.len)] = '?';
        var result = func(name);
        std.mem.doNotOptimizeAway(&result);
    }

    const elapsed = timer.read();

    return elapsed / iterations;
}

About 500KiB removed from a ReleaseSmall build of aro:
1.8M arocc-master
1.3M arocc-dafsa

$ bloaty arocc-dafsa -- arocc-master
    FILE SIZE        VM SIZE
 --------------  --------------
  +8.1% +22.9Ki  +8.1% +22.9Ki    .data.rel.ro
  -0.1%      -8  -0.1%      -8    .eh_frame_hdr
  -1.4% -2.41Ki  -1.4% -2.41Ki    .data
 -35.5% -49.4Ki -35.5% -49.4Ki    .eh_frame
 -56.8%  -201Ki -56.8%  -201Ki    .rodata
 -30.4%  -258Ki -30.4%  -258Ki    .text
 -26.9%  -488Ki -26.9%  -488Ki    TOTAL

Compile time of zig build is reduced by around a second:
$ hyperfine "git checkout master; zig build" "git checkout dafsa; zig build" --prepare "rm -rf zig-cache" --runs 3 --warmup 1
Benchmark #1: git checkout master; zig build
  Time (mean ± σ):     11.760 s ±  0.024 s    [User: 11.387 s, System: 0.605 s]
  Range (min … max):   11.745 s … 11.788 s    3 runs

Benchmark #2: git checkout dafsa; zig build
  Time (mean ± σ):     10.523 s ±  0.016 s    [User: 10.121 s, System: 0.608 s]
  Range (min … max):   10.505 s … 10.534 s    3 runs

Summary
  'git checkout dafsa; zig build' ran
    1.12 ± 0.00 times faster than 'git checkout master; zig build'

Unit tests run faster:
Benchmark #1: ./unit-tests-master
  Time (mean ± σ):     224.9 ms ±   2.6 ms    [User: 210.2 ms, System: 14.5 ms]
  Range (min … max):   220.7 ms … 230.1 ms    13 runs

Benchmark #2: ./unit-tests-dafsa
  Time (mean ± σ):      97.4 ms ±   2.6 ms    [User: 83.1 ms, System: 14.2 ms]
  Range (min … max):    94.2 ms … 103.5 ms    30 runs

Summary
  './unit-tests-dafsa' ran
    2.31 ± 0.07 times faster than './unit-tests-master'

Record tests run slightly slower (not sure why):
Benchmark #1: ./record-runner-master test/records
  Time (mean ± σ):     10.283 s ±  0.037 s    [User: 118.281 s, System: 0.261 s]
  Range (min … max):   10.262 s … 10.327 s    3 runs

Benchmark #2: ./record-runner-dafsa test/records
  Time (mean ± σ):     10.950 s ±  0.209 s    [User: 123.950 s, System: 0.284 s]
  Range (min … max):   10.796 s … 11.187 s    3 runs

Summary
  './record-runner-master test/records' ran
    1.06 ± 0.02 times faster than './record-runner-dafsa test/records'

Integration test times are ~unchanged:
Benchmark #1: ./test-runner-master /home/ryan/Programming/zig/arocc/test/cases zig
  Time (mean ± σ):     382.8 ms ±   7.2 ms    [User: 300.9 ms, System: 88.0 ms]
  Range (min … max):   373.2 ms … 393.2 ms    10 runs

Benchmark #2: ./test-runner-dafsa /home/ryan/Programming/zig/arocc/test/cases zig
  Time (mean ± σ):     392.9 ms ±   3.5 ms    [User: 308.5 ms, System: 90.8 ms]
  Range (min … max):   388.9 ms … 399.7 ms    10 runs

Summary
  './test-runner-master /home/ryan/Programming/zig/arocc/test/cases zig' ran
    1.03 ± 0.02 times faster than './test-runner-dafsa /home/ryan/Programming/zig/arocc/test/cases zig'

Shout out to @Validark for making me aware of DAFSA's.

Some notes:

The fields of BuiltinFunction were kept the same just to make the changes to the source code outside of BuiltinFunction.zig minimal, but because going from Tag to BuiltinFunction is now essentially free (it's just an array access), it probably makes sense to always just store BuiltinFunction.Tag and never BuiltinFunction. This would also allow removing the tag field from BuiltinFunction (but it doesn't reduce the @sizeOf(BuiltinFunction) so removing the field wouldn't necessarily provide an immediate benefit)
I just downloaded whatever the latest .def files were from https://github.com/llvm/llvm-project/tree/main/clang/include/clang/Basic and used those, which may not be what you want (maybe a tagged release of LLVM would be preferred?).
The new generate_builtins_dafsa.zig cannot handle macros that span multiple lines, which there are some of in the .def files (but AFAICT they are only used in new macros that aren't supported like TARGET_BUILTIN)
There are new macros that are unsupported: TARGET_BUILTIN, CUSTOM_BUILTIN, and UNALIASED_CUSTOM_BUILTIN
There is a new .def file that is skipped: BuiltinsSME.def

The generate script outputs some information about what is skipped and why, here's it's output for generating the BuiltinFunction.zig in this PR:
$ zig run scripts/generate_builtins_dafsa.zig --main-pkg-path . -- scripts/data/Builtins*.def
__builtin_arm_prefetch: param_str changed to "!"
__builtin_arm_rsr64: param_str changed to "!"
__builtin_arm_wsr64: param_str changed to "!"
__builtin_is_constant_evaluated: unknown language 'CXX_LANG', skipping
objc_msgSend: unknown header 'OBJC_MESSAGE_H', skipping
objc_msgSend_fpret: unknown header 'OBJC_MESSAGE_H', skipping
objc_msgSend_fp2ret: unknown header 'OBJC_MESSAGE_H', skipping
objc_msgSend_stret: unknown header 'OBJC_MESSAGE_H', skipping
objc_msgSendSuper: unknown header 'OBJC_MESSAGE_H', skipping
objc_msgSendSuper_stret: unknown header 'OBJC_MESSAGE_H', skipping
objc_getClass: unknown header 'OBJC_RUNTIME_H', skipping
objc_getMetaClass: unknown header 'OBJC_RUNTIME_H', skipping
objc_enumerationMutation: unknown header 'OBJC_RUNTIME_H', skipping
objc_read_weak: unknown header 'OBJC_OBJC_AUTO_H', skipping
objc_assign_weak: unknown header 'OBJC_OBJC_AUTO_H', skipping
objc_assign_ivar: unknown header 'OBJC_OBJC_AUTO_H', skipping
objc_assign_global: unknown header 'OBJC_OBJC_AUTO_H', skipping
objc_assign_strongCast: unknown header 'OBJC_OBJC_AUTO_H', skipping
objc_exception_extract: unknown header 'OBJC_OBJC_EXCEPTION_H', skipping
objc_exception_try_enter: unknown header 'OBJC_OBJC_EXCEPTION_H', skipping
objc_exception_try_exit: unknown header 'OBJC_OBJC_EXCEPTION_H', skipping
objc_exception_match: unknown header 'OBJC_OBJC_EXCEPTION_H', skipping
objc_exception_throw: unknown header 'OBJC_OBJC_EXCEPTION_H', skipping
objc_sync_enter: unknown header 'OBJC_OBJC_SYNC_H', skipping
objc_sync_exit: unknown header 'OBJC_OBJC_SYNC_H', skipping
NSLog: unknown header 'FOUNDATION_NSOBJCRUNTIME_H', skipping
NSLogv: unknown header 'FOUNDATION_NSOBJCRUNTIME_H', skipping
addressof: '&' in params str 'v*v&', skipping
__addressof: '&' in params str 'v*v&', skipping
as_const: '&' in params str 'v&v&', skipping
forward: '&' in params str 'v&v&', skipping
forward_like: '&' in params str 'v&v&', skipping
move: '&' in params str 'v&v&', skipping
move_if_noexcept: '&' in params str 'v&v&', skipping
__builtin_addressof: '&' in params str 'v*v&', skipping
__builtin_function_start: '&' in params str 'v*v&', skipping
__builtin_coro_resume: unknown language 'COR_LANG', skipping
__builtin_coro_destroy: unknown language 'COR_LANG', skipping
__builtin_coro_done: unknown language 'COR_LANG', skipping
__builtin_coro_promise: unknown language 'COR_LANG', skipping
__builtin_coro_size: unknown language 'COR_LANG', skipping
__builtin_coro_align: unknown language 'COR_LANG', skipping
__builtin_coro_frame: unknown language 'COR_LANG', skipping
__builtin_coro_noop: unknown language 'COR_LANG', skipping
__builtin_coro_free: unknown language 'COR_LANG', skipping
__builtin_coro_id: unknown language 'COR_LANG', skipping
__builtin_coro_alloc: unknown language 'COR_LANG', skipping
__builtin_coro_begin: unknown language 'COR_LANG', skipping
__builtin_coro_end: unknown language 'COR_LANG', skipping
__builtin_coro_suspend: unknown language 'COR_LANG', skipping
read_pipe: unknown language 'OCL_PIPE', skipping
write_pipe: unknown language 'OCL_PIPE', skipping
reserve_read_pipe: unknown language 'OCL_PIPE', skipping
reserve_write_pipe: unknown language 'OCL_PIPE', skipping
commit_write_pipe: unknown language 'OCL_PIPE', skipping
commit_read_pipe: unknown language 'OCL_PIPE', skipping
sub_group_reserve_read_pipe: unknown language 'OCL_PIPE', skipping
sub_group_reserve_write_pipe: unknown language 'OCL_PIPE', skipping
sub_group_commit_read_pipe: unknown language 'OCL_PIPE', skipping
sub_group_commit_write_pipe: unknown language 'OCL_PIPE', skipping
work_group_reserve_read_pipe: unknown language 'OCL_PIPE', skipping
work_group_reserve_write_pipe: unknown language 'OCL_PIPE', skipping
work_group_commit_read_pipe: unknown language 'OCL_PIPE', skipping
work_group_commit_write_pipe: unknown language 'OCL_PIPE', skipping
get_pipe_num_packets: unknown language 'OCL_PIPE', skipping
get_pipe_max_packets: unknown language 'OCL_PIPE', skipping
enqueue_kernel: unknown language 'OCL_DSE', skipping
get_kernel_work_group_size: unknown language 'OCL_DSE', skipping
get_kernel_preferred_work_group_size_multiple: unknown language 'OCL_DSE', skipping
get_kernel_max_sub_group_size_for_ndrange: unknown language 'OCL_DSE', skipping
get_kernel_sub_group_count_for_ndrange: unknown language 'OCL_DSE', skipping
to_global: unknown language 'OCL_GAS', skipping
to_local: unknown language 'OCL_GAS', skipping
to_private: unknown language 'OCL_GAS', skipping
__builtin_store_half: unknown language 'ALL_OCL_LANGUAGES', skipping
__builtin_store_halff: unknown language 'ALL_OCL_LANGUAGES', skipping
__builtin_load_half: unknown language 'ALL_OCL_LANGUAGES', skipping
__builtin_load_halff: unknown language 'ALL_OCL_LANGUAGES', skipping
__builtin_get_device_side_mangled_name: unknown language 'CUDA_LANG', skipping
__builtin_hlsl_wave_active_count_bits: unknown language 'HLSL_LANG', skipping
__builtin_hlsl_create_handle: unknown language 'HLSL_LANG', skipping
__builtin_ms_va_start: '&' in params str 'vc*&.', skipping
__builtin_ms_va_end: '&' in params str 'vc*&', skipping
__builtin_ms_va_copy: '&' in params str 'vc*&c*&', skipping
unknown target for file 'scripts/data/BuiltinsSME.def', skipping
3948 builtins, max params: 12

I can't view all the changes from my phone but I'm curious how your manual generation compares to the code that the compiler would generate for you automatically. If you sort the builtins by length (greatest to least) and do:
inline for (builtins) |builtin| {
    if (std.mem.eql(u8, cur_identifier, builtin)) {
        return comptime lookup(<...>);
    }
}

How good does LLVM do by default?

@Validark, that code is basically exactly what stringToEnum does, so here's the benchmark with the enum fields sorted by length:
Lookup time (does name exist?):

------------------- dafsa ------------------
            always found: 83ns per lookup
not found (random bytes): 31ns per lookup
 not found (1 char diff): 83ns per lookup
------------------- enum -------------------
            always found: 1191ns per lookup
not found (random bytes): 68ns per lookup
 not found (1 char diff): 1184ns per lookup

dafsa is 14.3x / 2.2x / 14.3x faster

Lookup time (name -> BuiltinFunction):

------------------- dafsa ------------------
            always found: 154ns per lookup
not found (random bytes): 34ns per lookup
 not found (1 char diff): 156ns per lookup
------------------- enum -------------------
            always found: 1186ns per lookup
not found (random bytes): 68ns per lookup
 not found (1 char diff): 1176ns per lookup

dafsa is 7.7x / 2.0x / 7.5x faster

Considerably better than the unsorted version, but the manually generated DAFSA is still quite a bit better.

Sorry for not digging in to the code more before asking. Very interesting! Looks like there's some improvements that could be made to LLVM (and stringToEnum).

Could the Tag be changed to a non-exahaustive enum?
Currently the information required for this is not directly stored anywhere in the generated code. It is possible to get a list of builtins indirectly by iterating over the data array indexes, and then using nameFromTag to get the name from the DAFSA which requires a buffer to write the name into (this is what BuiltinsIterator does).

There also doesn't seem to be a fast path for trying to lookup a name shorter than or longer than exist in the set.
Will add that (there's already a longest_builtin_name const used by BuiltinsIterator for its name buffer). However, shortest will be 3 currently, so unsure if it'll make anything faster.

By non-exhaustive enum I meant enum(u16) { _ } so that it doesn't cast automatically to other types.

Updated:

Tag is now enum(u16) { _ }
Updated --main-pkg-path to --main-mod-path
There are fast path length checks in exists and uniqueIndex

The length checks only affect the not found (random bytes) benchmark (since that's the only one where the length could be outside of the shortest...longest range):
Lookup time (does name exist?):

------------------- dafsa ------------------
            always found: 88ns per lookup
not found (random bytes): 24ns per lookup
 not found (1 char diff): 87ns per lookup
------------------- enum -------------------
            always found: 3682ns per lookup
not found (random bytes): 6681ns per lookup
 not found (1 char diff): 3729ns per lookup

dafsa is 41.8x / 278.4x / 42.9x faster

Lookup time (name -> BuiltinFunction):

------------------- dafsa ------------------
            always found: 164ns per lookup
not found (random bytes): 25ns per lookup
 not found (1 char diff): 159ns per lookup
------------------- enum -------------------
            always found: 3741ns per lookup
not found (random bytes): 6919ns per lookup
 not found (1 char diff): 3688ns per lookup

dafsa is 22.8x / 276.8x / 23.2x faster

Did the "fast path" improve actual compile times? If the vast majority of identifiers fall within the target range then it feels like you'll take branch misses that will hurt more than help.

Unsure why you're asking about compile times since the length check is runtime only, but the fast path seems to have had either no effect or a very slightly negative effect on the "always found" and "not found (1 char diff)" benchmarks which always fail the fast path (compare the dafsa results in https://github.com/Vexu/arocc/pull/524#issuecomment-1763215387 vs the OP).
May or may not be worth it, but doesn't seem to provide enough of an obvious downside that it's worth worrying about too much.

Sorry for the ambiguity, by "compile times" I meant how long it takes to parse and do the pass that needs to identify builtins. You say this "fast path" optimization may only slightly worsen performance, I'm saying that if that's the case it's not worth it as an optimization.
Your branch predictor can hurt you, and it can backfire. If you had half of all identifiers going down the early out "fast path" and an equal number going down the DAFSA, and the order was completely random so the branch predictor cannot "find a pattern" (get lucky), you would expect to guess wrong 50% of the time. A branch mispredict can waste a lot of cycles. Given the very low number of nanoseconds in your measurements, it seems to me a branch mispredict might actually take up, I don't know, 10% of execution time.
In my Accelerated Zig Parser's tokenizer, there is a fast keyword identifier algorithm. I tried adding a "fast path", actually I tried out multiple different early outs, and they all hurt performance. It turned out that the extra work we could avoid with the "fast path" was less than the cost of a mispredict. Since your main path is extremely fast, adding an early out can hurt performance.

I currently don't have a benchmark that will allow me to test it properly in a real-world scenario, would need to set something up for that. I can fully believe the "fast path" is detrimental, and I'm sure there's plenty of other performance gains that can be squeezed out of my implementation, but I'm okay with leaving that on the table for now.


Finding kernel source

Hi
Using nsight compute, I see a kernel named res2_sm_80_kernel for resnet50.
Finished setting up SUT.
Starting warmup. Running for a minimum of 0 seconds.
==PROF== Profiling "convActPoolKernelV2" - 0 (1/200000): 0%....50%....100% - 1 pass
==PROF== Profiling "res2_sm_80_kernel" - 1 (2/200000): 0%....50%....100% - 1 pass

The command is
./build/bin/harness_default \
--logfile_outdir="./build/logs/2023.02.20-15.12.02/m2022_TRT/resnet50/Offline" \
--logfile_prefix="mlperf_log_" \
--performance_sample_count=2048 \
--gpu_copy_streams=2 \
--gpu_inference_streams=1 \
--run_infer_on_copy_streams=false \
--warmup_duration=0.0 \
--gpu_batch_size=1024 \
--map_path="./data_maps/imagenet/val_map.txt" \
--tensor_path="./build/preprocessed_data/imagenet/ResNet50/int8_linear" \
--use_graphs=false \
--gpu_engines="./build/engines/m2022/resnet50/Offline/resnet50-Offline-gpu-b1024-int8.lwis_k_99_MaxP.plan" \
--mlperf_conf_path="./measurements/m2022_TRT/resnet50/Offline/mlperf.conf" \
--user_conf_path="./measurements/m2022_TRT/resnet50/Offline/user.conf" \
--max_dlas=0 \
--scenario Offline \
--model resnet50

I searched the code to see the kernel code, but it seems that this name is part of another Nvidia library. Also with the name sm_80 I expect that this name has been formed by an engine, so this complete name doesn't exist in the libraries.
I also wasn't able to find the higher level C++ function that invokes this kernel.
Any idea about how to find details of this kernel?

That kernel might be part of the TensorRT library, which ships in binary form.

Thanks for the reply. I have recently encountered a problem with resnet50 and Nvbit which I have raised the issue here. I think you also have worked with these two in your tests with MLPerf benchmarks. Have you seen a similar thing before? I have stuck at that problem and tools are closed source.


Exclude from Source Tree

Is it possible to add an argument so that any excluded files/folders/extensions are also excluded from the source tree?
I am currently working with some folders that have thousands of .npy files, or .wav, etc, and this means the source tree can get a little bit heavy!
Thanks for this great tool!

Just implemented this! Usage:
code2prompt path/to/codebase --exclude="*.npy,*.wav" --exclude-from-tree

Thank you for the feature request! ❤ 🙌


Upgrade golang versioin to 1.8.1

With golang1.6.1, when 'make docker', we will encounter the following issue,
api/v1/cmd/example-executor/main.go:4:2: cannot find package "context" in any of:
        /go/src/github.com/mesos/mesos-go/api/v1/cmd/vendor/context (vendor tree)
        /go/src/github.com/mesos/mesos-go/api/v1/vendor/context
        /usr/local/go/src/context (from $GOROOT)
        /go/src/context (from $GOPATH)
Makefile:108: recipe for target 'docker' failed

This is because golang has no package "context", so upgrade golang to 1.8.1 .
Signed-off-by: Shukui Yang<EMAIL_ADDRESS>

Changes Unknown when pulling fefe5a24a0949ed416f5bb38529b196209eaba42 on keloyang:golang-1.8.1 into ** on mesos:master**.

thanks for the PR!


Snyk upgrades

Upgrade vulnerable dependencies as stated by Snyk
Signed-off-by: Sebastian Becker<EMAIL_ADDRESS>Resolves #18 #30 #34 #42 #43 #44

The PR has one vulnerability left being identified by the Snyk Security Check

where the vulnerable dependency defined exposes a low risk vulnerability

with no unaffected version available as of today

As the dependency is introduced indirectly minio -> okhttp -> kotlin-stdlib, it cannot easily be replaced.
With the vulnerability being ranked low I'd therefore suggest to accept the risk left for the time being and upgrade the dependency once a fix is available.


Fix the 'quarkus.jib.base-native-image' property

resolves #177

The change looks fine to me and allows us to be explicit about the base image used.


Disable too-many-*

Description:
Disable too-many-* for pylint.

[x] too-many-locals
[x] too-many-instance-attributes
[x] too-many-arguments
[x] too-many-branches
[x] too-many-public-methods

Related issue (if applicable): fixes #4090
Checklist:
If the code communicates with devices, web services, or third-party tools:

[x] Local tests with tox run successfully. Your PR cannot be merged unless tests pass

If the code does not interact with devices:

[x] Local tests with tox run successfully. Your PR cannot be merged unless tests pass

Please use an automated tool to remove these lines!

Sure, I'm not going to edit 300 lines manually.

OOps, merge conflicts with some of your other cleanups

🐬  Ok to merge when conflicts resolved.

That was foreseeable.


test floating point casting better

@bors r+

:pushpin: Commit b8a817fc03ada9a92df7fe916f1933f5b81f84af has been approved by RalfJung

:hourglass: Testing commit b8a817fc03ada9a92df7fe916f1933f5b81f84af with merge fc30266540d4e04c018046bb69098adf68ba9f6c...

:sunny: Test successful - checks-travis, status-appveyor
Approved by: RalfJung
Pushing fc30266540d4e04c018046bb69098adf68ba9f6c to master...


Renaming Execution Manager component to Template Manager

This pull contains changes w.r.t renaming of Execution Manger component to Template Manager. The changes will be incorporated in following versions;
carbon.analytics.common: 5.1.0-SNAPSHOT
carbon.analytics: 1.0.6-SNAPSHOT
carbon.event.processing: 2.1.0-SNAPSHOT
Please review and merge

Closing this since the same PR is sent to master branch in: https://github.com/wso2/product-apim/pull/1031


Segmentation Fault in Ruby 3.2

Hey @danielpclark ,
Hope you are doing well.
I've tried adding support for Ruby 3.2 for my project that is using Rutie and I'm now getting a SegFault (here's a PR that adds Ruby 3.2 as a target and you should be able to see logs from GH Actions for a full stack trace).
As far as I'm able to decipher it — the issue is that Rutie bindings for Integer use Fixnum class (when implementing the VerifiedObject trait) which has been removed from Ruby 3.2. As a result the call to Rust crashes if it takes an Integer as input.
Hope it's a relatively quick fix.

Thanks for the info.  I'm currently coaching 3 teams over the basketball season so I haven't had much time to spare.  I haven't yet moved up the code and tests for Ruby 3 but that is next on my agenda.  Also the CI I was using before switched domains and no longer provides free service for me so I need to move the test matrix over to Github Actions, or something as capable as the previous CI.  Perhaps both.
I understand your desire for this to be done quickly, but if no one else is picking this up at this time it'll have to wait until I'm free.

@danielpclark perfectly understandable, no problem at all 👍 I might get someone on our side to put a PR together

It appears that the memory layout of things has changed in Ruby 3.2; I just banged my head against it for #174.  My commiserations to whoever has to chase down all the corner cases.

any news about this?

@EmmN , My main computer was down for 5 months (besides being busy coaching) and I got it up and running last week.  I have an additional computer I'll be finishing building this week for AI related work.  After that I'll likely get the CI test suite finalized with full Ruby 2 suite on Github Actions to be a 1 for 1 setup to as it was on Travis CI.  Then I'll begin the Ruby 3 migration (Lord willing).
That is the current update.

@danielpclark Thanks! I believe that moving to rb-sys would be a good idea.

Hey! Any updates on ruby 3 support?


Luck based effects on card dealing.

I have been discussing with Shadow from the Cascadia team about general ways to implement a Luck based effect on the "randomness" of dealing cards to the player. I.E. at higher luck levels you will get dealt better cards. I will copy over his suggestions, I am thinking that certain degrees of combinations of his suggestions might work best in order to achieve a more RPG feel to gambling.

From shadow:
1-2 is considered "low int" in NV with the stupid dialogue options, so 1-2 is bad luck, as an assumption
so make their first card random
but then figure out how far they are from busting/blackjack
and deal their second card in a set of ranges based on luck
higher luck gets lower cards/higher chance of hitting 21
low/bad luck gets higher cards/higher chance of busting.
You may also not want to do that on every turn
So some hands for the player are truly random(edited)
but you could work in that system that works off of luck instead too, and throw that one to the player
If Player.GetValue(Luck) <= Utility.RandomInt(1, 50)
; luck based hand
Else
; random hand
EndIf
1 in 5 chance with maxed luck, 1 in 50 chance with min luck
Of couse RandomInt(1,50) could be tweaked too
range could be 1-100 for 10% chance with 10 luck
or lower for higher chances
You could even calculate the max range for randomint off of luck

I agree we should factor in the players luck attribute to the odds of winning a game. The technical details are a little off base though. The card that gets drawn from a deck is much more than simply a random number or an index in a list so just returning a random number wont do the trick.
Lets recap the goal here. We want to increase the players chance of winning a game when their luck is high and decrease the chance of winning when their luck is low. To achieve this we should do it exactly the same way it would be done in real life. In real life you would decrease the odds of winning in favor of the house by stacking the deck with multiple decks of cards. Since the Deck class models real life as closely as I could we can add more card entries to the decks internal card array which will decrease the chances of the player winning a game.
Here is a chart of the odds based on the amount of decks used in a game of black jack.

Number of Decks
House Advantage

Single Deck
0.17%

Double Deck
0.46%

Four Decks
0.60%

Six Decks
0.64%

Eight Decks
0.65%

With that, we increase the amount of decks used the lower a players luck attribute is. When a game uses a single deck of 52 cards the player should have a luck of 10.
So I propose a formula like this.
(10 - LUCK) + 1 = DecksUsed

Luck
Decks

1
10

2
9

3
8

4
7

5
6

6
5

7
4

8
3

9
2

10
1

That's genius! And very realistic as well, I love it! But...how smoothly can you implement that? Of course, a simple way would be to run a set of comparisons against the player's Luck stat even before the cards are "shuffled" then add decks based on the stat.

Very smoothly if I may toot my own horn. Off the top of my head I can expose like a int Depth property on the Deck class. Then when NewCards is called it can add 52 card deck x times. That could potentially be up to 520 entries in the internal array so I will need to find a workaround for the 128 element array limit. Since this is a predictable maximum using multiple internal arrays may be a good option.
Deck Class

Wasn't aware of that limit, ugh if this were C I'd say use a pointer in the last element of the array to point to the next array...but alas. In that case, multiple internal arrays would work (pretty sure I know what means).

Leaving this open, one of those things we can do quickly, a simple check for the multiplier on the payout should suffice for blackjack

The user ForsakenShell had some thoughts to add to the conversation that I found interesting.

I was suggest using a logarithmic scale so as your luck gets higher it effects game outcomes less and less.
Example: Log( 10 ) ^Luck
When it hits 7-8 luck it starts really slowing down, after 10 it crawls.

Produces a range of 0-10 for luck 1-10 where 1 = 0, 5 = 0.7; 7 = 0.85, 10 = 1.
Going beyond 10 to 20 only yields 1.3.
I didn't hit any snags with the mod yet though but I didn't get to test it for long either.

Additional Testing

Example: 5 * Log( 10 ) ^ Luck
Think of the last provided equation as "% chance the player will get a favourable card"
At 10 luck it yields 5%.
At 20 luck is only ~6.5%.
At 1 luck it is 0%.

Thanks for adding to the conversation E.

User Feedback

User Feedback


release: 0.5.1

Automated Release PR
0.5.1 (2024-12-11)
Build

deps: bump Serilog and Serilog.Settings.Configuration (#228) (1d9135f)
deps: bump Serilog, Serilog.AspNetCore, Serilog.Settings.Configuration, Serilog.Sinks.Console and Microsoft.Extensions.Options (#233) (d5aa980)
deps: bump the npm_and_yarn group (#231) (800be32)
deps: bump the npm-dependencies group across 1 directory with 4 updates (#234) (f764d86)
deps: bump the nuget-dependencies group with 2 updates (#235) (0bac0f6)

This PR was generated with Release Please. See documentation.

:robot: Created releases:

0.5.1
:sunflower:


Refactor configurations

This moves all configurations from org.osiam.Osiam to their dedicated
configuration classes.
See the individual commits for further details.
This time it should actually work and not break everything :)

Thank you!


nbstripout: fix build on darwin

Motivation for this change
Build fails on darwin because, for some reason, echo -n isn't handled properly: https://hydra.nixos.org/build/52896770/nixlog/14
I patched the failing test on darwin to use \c at the end of the string instead of -n flag.
Things done

[x] Tested using sandboxing
(nix.useSandbox on NixOS,
or option build-use-sandbox in nix.conf
on non-NixOS)
Built on platform(s)

[x] NixOS
[ ] macOS
[ ] Linux

[x] Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
[x] Tested execution of all binary files (usually in ./result/bin/)
[x] Fits CONTRIBUTING.md.

Don't merge yet. I need to work on this a little bit more.

Now this should be good to merge.


Interlocked on floats (at least Max/Min)

Is your feature request related to a problem? Please describe.
With compute shaders, atomics have become a big part of shaders and the lack of float support can be quite annoying sometimes. I understand that atomic add on a float might be hard because of possible hardware support, but min/max could be supported in software too. Atomic min/max would essentially be possible by doing the following conversion before min/max: u = asuint(f); u = u >> 31 ? ~u : (u | (1 << 31)). Then doing atomics using u and reversing it when reading back. Even though this is possible manually, it'd be great if the language supports this without floating point trickery.
Describe the solution you'd like
Support for interlocked floats, most importantly min/max. Add would be nice too, but understandable if it can't be supported. Float atomics have existed in OpenGL GLSL with an NV specific extension.
Describe alternatives you've considered
Doing it manually, but might be an obstacle for new programmers.
Additional context
N.A.

@devshgraphicsprogramming Yes, if you're using Vulkan you can enable the VK_EXT_shader_atomic_float if supported. DirectX12 to my knowledge doesn't support it (because DXIL doesn't).
As a sidenote; the solution I provided doesn't work with NaNs because NaNs always return false when compared, while my hack would assume NaNs are real numbers so they'd get turned into something bigger than inf. So just don't throw in a NaN and it should be fine :). As for correct IEEE754 behavior for NaN: min is: a = a < b ? a : b; Then for a NaN as 'a' that'd return b always and for max too. Even if it's a NaN passed as b, it will always be returned. So imo ignoring the NaN in the min/max is the IEEE754 comformant-ish way to do it (except if it's the min/max are only performed on NaNs).
I saw @jeremyong liked this issue and also made a good blogpost explaining this in further detail at https://www.jeremyong.com/graphics/2023/09/05/f32-interlocked-min-max-hlsl/. Just to note, this solution does still work on halfs and doubles as well; but the sign check and shift should be corrected to 15 or 63 respectively of course. In fact it works with any IEEE754 compliant format that puts the sign bit, then exponent and then mantissa in that order. N = mantissa + exponent (15 = half, 31 = float, 63 = double).

just to clarify I'm not trivializing or against this being implemented in HLSL/DXC and added to DXIL, just giving pointers if you want to achieve this "today" in SPIR-V env.

As a sidenote; the solution I provided doesn't work with NaNs because NaNs always return false when compared, while my hack would assume NaNs are real numbers so they'd get turned into something bigger than inf. So just don't throw in a NaN and it should be fine :). As for correct IEEE754 behavior for NaN: min is: a = a < b ? a : b; Then for a NaN as 'a' that'd return b always and for max too. Even if it's a NaN passed as b, it will always be returned. So imo ignoring the NaN in the min/max is the IEEE754 comformant-ish way to do it (except if it's the min/max are only performed on NaNs). I saw @jeremyong liked this issue and also made a good blogpost explaining this in further detail at https://www.jeremyong.com/graphics/2023/09/05/f32-interlocked-min-max-hlsl/. Just to note, this solution does still work on halfs and doubles as well; but the sign check (shift) and mask should be corrected to 15 or 63 respectively of course. In fact it works with any IEEE754 compliant format that puts the sign bit, then exponent and then mantissa in that order. N = mantissa + exponent (15 = half, 31 = float, 63 = double). (Though uint64_t atomics would be needed for doubles and 1 << N should be a uint64_t shifted first too)

This is obviously a really cool technique.
As a sidenote to a sidenote, we can do all sorts of "atomic" operations with CAS loops but for this and for the trick above it gets really nasty to maintain the code that does this without having any sort of reference type, right now you cam abuse the bug that #5377 will fix soon and have
template<typename T>
T myEsotericAtomic(inout T rval, in T operand);

and do whatever you like inside (CAS loop, call to an inline SPIR-V instrinsic), plus have this work both with groupshared, RWStructuredBuffer, and if new BDA ships before #5377 even with the result of vk::BufferPointer::Get().
Once #5377 ships before we're given true T& references or some sort of a crutch, the only way to implement this is with a macro, even if you use an accessor pseudo-lambda/functor-struct simply because you'll have to copy&paste the code into the method definition a million times.


Image sync

Summary
Brings image synchronisation to the catchall operations of fedcloud.
Uses atrope for managing images at the sites by generating the configuration for every VO that's avaialable at the AppDB

Related issue :

Merging tomorrow to react to potential failures...


[test] fix rush integration-test

Some of the rush projects are missing integration test scripts and cause rush integration-test to fail as this command expects every project has these scripts.
This PR adds stub integration test scripts to projects that miss them.

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


Updates network type mapping for cidr to (IPAddress, int)

#407 is getting complicated. Splitting this off to simplify review.

Thanks, this also fixes the incorrect NpgsqlDbType mapping for macaddr8.
Merged via 6655bbbd17b415270be78fc729e419fd89db3641, amended slightly to remove unwanted whitespace changes and for more complete commit message.


Use array_element instead of telescope in names, model_parameter, db_handler

Mostly a scripted name change from telescope to array_element in the modules mention above. This generalizes the functions and names to take into account the we simulate telescopes and calibration devices.
Closes #871

One thing to note regarding this pull request: we are still using two different names for the same thing: instrument and array_element. `instrument is used mostly in database entries.
(I am not suggesting to change this, just a remark)


WFCORE-6472 Remove the remoting subsystem transformers and long deprecated resources/attributes

https://issues.redhat.com/browse/WFCORE-6472
https://issues.redhat.com/browse/WFCORE-6473 (implicitly addressed)
Resources and attributes deprecated since WF23 have been dropped.  This includes the weird handling described in WFCORE-6473.
I've added an enumeration of supported model versions, to be referenced by future transformers.
This PR also adds new 6.0 version of schema that prunes obsolete elements/attributes for which there is no longer any model in which to persist.
The parser/writer for version 6.0 is now based on PersistentResourceXMLDescription, and the 6.0 schema simplified accordingly.
Subsystem tests have also been parameterized to accommodate future schema versions, so that parsing of legacy schemas tests do not get dropped.

Core -> Full Integration Build 12736 outcome was FAILURE using a merge of 7e3f188528f5cc39d944fe476b04796d34ebb0dc
Summary: Exit code 1 (Step: Build & test full (Maven)) Build time: 00:04:20

Core -> WildFly Preview Integration Build 12817 outcome was FAILURE using a merge of 7e3f188528f5cc39d944fe476b04796d34ebb0dc
Summary: Exit code 1 (Step: Build & test full (Maven)) Build time: 00:04:24

Core -> Full Integration Build 12737 outcome was FAILURE using a merge of b63b20c5f81f32334858d403c91a2919aa46d902
Summary: Exit code 1 (Step: Build & test full (Maven)) Build time: 00:04:22

Core -> WildFly Preview Integration Build 12818 outcome was FAILURE using a merge of b63b20c5f81f32334858d403c91a2919aa46d902
Summary: Exit code 1 (Step: Build & test full (Maven)) Build time: 00:04:33

Core -> Full Integration Build 12951 outcome was FAILURE using a merge of b63b20c5f81f32334858d403c91a2919aa46d902
Summary: Tests passed: 1443, ignored: 18; exit code 1 (Step: Build & test full (Maven)) Build time: 00:10:39

@bstansberry FYI - full integration failures are due to these lines that need to be removed in main wildfly:
https://github.com/wildfly/wildfly/blob/main/ee-feature-pack/galleon-shared/src/main/resources/feature_groups/remoting.xml#L5
https://github.com/wildfly/wildfly/blob/main/ee-feature-pack/galleon-shared/src/main/resources/feature_groups/unsecured-basic-profile.xml#L6
It is unclear to me whether those changes can be made independently from this PR.
Side note: are we ready to merge wildfly-core back into wildfly yet?

Closing for now.  I seem to have screwed something up.


feat: tree interaction

resolve #19
The verified user can not use the /tree endpoint to travel through the entity-teacher-course graph.

Maybe we can split this endpoint into three? i.e.

/tree/entity
/tree/course
/tree/teacher

So that we don't need to validate type and the response type becomes simpler.
@JacobLinCool How do u think?

Maybe we can split this endpoint into three

I think we should ask @UniCourse-TW/frontend, since they are the main user of the client library.
Is
uni.req("/tree", { body: { type, id } })

v.s.
uni.req(`/tree/${type}`, { body: { id } })

I think we should ask @UniCourse-TW/frontend, since they are the main users of the client library.
uni.req("/tree", { body: { type, id } })

v.s.
uni.req(`/tree/${type}`, { body: { id } })

There may be third option, i.e. a wrapper for /tree API.

I'll choose the third option if I am a user.

for me, I prefer to use above one (uni.req("/tree")) or to have third option.
let's go with the third option


after update plugin didn't work

<c-n><c-n>s
<c-n><c-n>a
<c-n><c-n>c

error message I got:
^[' cannot be replayed at 3 cursors location
my .vimrc
"multi cursor pluggin
"let g:multi_cursor_use_default_mapping=0
" Default mapping
let g:multi_cursor_next_key='<C-n>' "next
let g:multi_cursor_prev_key='<C-k>' "prev
let g:multi_cursor_skip_key='<C-x>' "skip
let g:multi_cursor_quit_key='<Esc>' "quit

@xavierartot try to add set nocompatible in your .vimrc.
With your .vimrc + set nocompatible I could not reproduce your issue.
If this fixed your bug, please close this issue.
Thanks :smile:

Doesn't help.
Here my software version:
vim --version && python --version
VIM - Vi IMproved 8.1 (2018 May 17, compiled May 18 2018 13:18:41)
macOS version
Included patches: 1
Compiled by Homebrew
Huge version without GUI.  Features included (+) or not (-):
+acl               +farsi             +mouse_sgr         -tag_any_white
+arabic            +file_in_path      -mouse_sysmouse    -tcl
+autocmd           +find_in_path      +mouse_urxvt       +termguicolors
-autoservername    +float             +mouse_xterm       +terminal
-balloon_eval      +folding           +multi_byte        +terminfo
+balloon_eval_term -footer            +multi_lang        +termresponse
-browse            +fork()            -mzscheme          +textobjects
++builtin_terms    -gettext           +netbeans_intg     +timers
+byte_offset       -hangul_input      +num64             +title
+channel           +iconv             +packages          -toolbar
+cindent           +insert_expand     +path_extra        +user_commands
-clientserver      +job               +perl              +vertsplit
+clipboard         +jumplist          +persistent_undo   +virtualedit
+cmdline_compl     +keymap            +postscript        +visual
+cmdline_hist      +lambda            +printer           +visualextra
+cmdline_info      +langmap           +profile           +viminfo
+comments          +libcall           -python            +vreplace
+conceal           +linebreak         +python3           +wildignore
+cryptv            +lispindent        +quickfix          +wildmenu
+cscope            +listcmds          +reltime           +windows
+cursorbind        +localmap          +rightleft         +writebackup
+cursorshape       -lua               +ruby              -X11
+dialog_con        +menu              +scrollbind        -xfontset
+diff              +mksession         +signs             -xim
+digraphs          +modify_fname      +smartindent       -xpm
-dnd               +mouse             +startuptime       -xsmp
-ebcdic            -mouseshape        +statusline        -xterm_clipboard
+emacs_tags        +mouse_dec         -sun_workshop      -xterm_save
+eval              -mouse_gpm         +syntax
+ex_extra          -mouse_jsbterm     +tag_binary
+extra_search      +mouse_netterm     +tag_old_static
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
  fall-back for $VIM: "/usr/local/share/vim"
Compilation: clang -c -I. -Iproto -DHAVE_CONFIG_H   -DMACOS_X -DMACOS_X_DARWIN  -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: clang   -L. -fstack-protector -L/usr/local/lib -L/usr/local/opt/libyaml/lib -L/usr/local/opt/openssl/lib -L/usr/local/opt/readline/lib  -L/usr/local/lib -o vim        -lncurses -liconv -framework AppKit   -mmacosx-version-min=10.13 -fstack-protector-strong -L/usr/local/lib  -L/usr/local/Cellar/perl/5.26.2/lib/perl5/5.26.2/darwin-thread-multi-2level/CORE -lperl -lm -lutil -lc  -L/usr/local/opt/python/Frameworks/Python.framework/Versions/3.6/lib/python3.6/config-3.6m-darwin -lpython3.6m -framework CoreFoundation  -lruby.2.5.1 -lobjc
Python 2.7.13```

Can you also please detail your testcase:
<c-n><c-n>s
<c-n><c-n>a
<c-n><c-n>c

Did you type those back to back, or are you saying that each one of those is triggering this issue?
Can you please send us a file example and clear instructions on which word we have to start with?
Did you really try the following minimal vimrc (vim -u minimal_vimrc); that implies no sourcing any other plugin ?

set nocompatible
"multi cursor pluggin
"let g:multi_cursor_use_default_mapping=0
" Default mapping
let g:multi_cursor_next_key='<C-n>' "next
let g:multi_cursor_prev_key='<C-k>' "prev
let g:multi_cursor_skip_key='<C-x>' "skip
let g:multi_cursor_quit_key='<Esc>' "quit

No response after 3 months, closing the issue.


Added charmhub badge to README.md

Added charmhub badge to README.md

let's try to keep conventional commits standard next time


Any plan about inpainting controlnet?

Inpainting is widely used. Do you have plans to train an inpainting controlnet?

Hi! Yes, we have plans to add inpainting

Inpainting is widely used. Do you have plans to train an inpainting controlnet?

https://github.com/huggingface/diffusers/blob/2d9ccf39b53325d95036776df0a8acfc39352256/src/diffusers/pipelines/controlnet_sd3/pipeline_stable_diffusion_3_controlnet_inpainting.py
Can we create a similar pipeline using current flux controlnet, or should we train a specific controlnet + inpainting model?

https://github.com/yishaoai/flux-controlnet-inpaint/ support flux + controlnet + inpaint now.


Update and rename setup.py to setup_Py3.py

Python3 installer

update installer for python3.Needs testing


Fix darwin tests

This fixes tests on Darwin.
There is three different issues here:

The default permissions of symbolic links on darwin are lrwxr-xr-x while on Linux they are lrwxrwxrwx. (Those permissions can't be changed, neither on Darwin nor on Linux, as far as I know, so it doesn't really make sense to assert on them - we don't try to restore it anyway). This PR skips that check.
It's currently not possible to change the timestamps of files on Darwin (I'm not sure if this is a limitation of Darwin or of the Go runtime). This PR skips the symlink timestamp checks on Darwin.
HFS+ doesn't support sub-second resolution for timestamps (the nanoseconds returned will be set to 0). This PR ignores the nanoseconds on Darwin and only checks up to second precision.

table flip

:green_heart: :dancer:

Heh, great! I'll have a look now

Looks good! :+1:


Source Control Problum

Type: Performance Issue
Earlier, I had a direct GitHub repo in my Source Control or from there, all my files were pushed to my GitHub repo, but since I have created a new user in my name on my laptop, all these files have been pushed to the source as well.
How will this problem be solved?
VS Code version: Code 1.86.1 (31c37ee8f63491495ac49e43b8544550fbae4533, 2024-02-07T09:08:20.941Z)
OS version: Windows_NT x64 10.0.22631
Modes:

System Info

Item
Value

CPUs
AMD Ryzen 5 5500U with Radeon Graphics          (12 x 2096)

GPU Status
2d_canvas: enabledcanvas_oop_rasterization: enabled_ondirect_rendering_display_compositor: disabled_off_okgpu_compositing: enabledmultiple_raster_threads: enabled_onopengl: enabled_onrasterization: enabledraw_draw: disabled_off_okskia_graphite: disabled_offvideo_decode: enabledvideo_encode: enabledvulkan: disabled_offwebgl: enabledwebgl2: enabledwebgpu: enabled

Load (avg)
undefined

Memory (System)
5.86GB (0.73GB free)

Process Argv
C:\Users\mohit\OneDrive\Desktop\Sharma Vishnu --crash-reporter-id 5a67b218-81d3-40dd-97ee-a41dc3eb3108

Screen Reader
no

VM
0%

Process Info
CPU %	Mem MB	   PID	Process
    0	   112	 12028	code main
    0	    12	  1304	   C:\Users\mohit\AppData\Local\Temp\vscode-stable-user-x64\CodeSetup-stable-903b1e9d8990623e3d7da1df3d33db3e42d80eda.exe /verysilent /log /update="C:\Users\mohit\AppData\Local\Temp\vscode-stable-user-x64\CodeSetup-stable-903b1e9d8990623e3d7da1df3d33db3e42d80eda.flag" /nocloseapplications /mergetasks=runcode,!desktopicon,!quicklaunchicon
    0	    42	  8684	     "C:\Users\mohit\AppData\Local\Temp\is-CH538.tmp\CodeSetup-stable-903b1e9d8990623e3d7da1df3d33db3e42d80eda.tmp" /SL5="$480144,97901463,828416,C:\Users\mohit\AppData\Local\Temp\vscode-stable-user-x64\CodeSetup-stable-903b1e9d8990623e3d7da1df3d33db3e42d80eda.exe" /verysilent /log /update="C:\Users\mohit\AppData\Local\Temp\vscode-stable-user-x64\CodeSetup-stable-903b1e9d8990623e3d7da1df3d33db3e42d80eda.flag" /nocloseapplications /mergetasks=runcode,!desktopicon,!quicklaunchicon
    0	   201	  1868	extensionHost [1]
    0	    44	  6424	     electron-nodejs (serverMain.js )
    0	    36	 11712	     "C:\Users\mohit\AppData\Local\Programs\Microsoft VS Code\Code.exe" "c:\Users\mohit\AppData\Local\Programs\Microsoft VS Code\resources\app\extensions\json-language-features\server\dist\node\jsonServerMain" --node-ipc --clientProcessId=1868
    0	    29	  5440	   crashpad-handler
    0	    96	  5996	window [2] (Issue Reporter)
    0	    75	  9484	shared-process
    0	    35	 14404	   utility-network-service
    0	   120	 14424	   gpu-process
    0	    55	 15540	fileWatcher [1]
    0	   231	 17172	window [1] (Sharma Vishnu - Visual Studio Code)

Workspace Info
|  Window (Sharma Vishnu - Visual Studio Code)
|    Folder (Sharma Vishnu): 0 files
|      File types:
|      Conf files:;

Extensions (4)

Extension
Author (truncated)
Version

es7-react-js-snippets
dsz
4.4.3

auto-rename-tag
for
0.1.10

codespaces
Git
1.16.10

vscode-icons
vsc
12.7.0

(1 theme extensions excluded)

A/B Experiments
vsliv368cf:30146710
vspor879:30202332
vspor708:30202333
vspor363:30204092
vscorecescf:30445987
vscod805cf:30301675
binariesv615:30325510
vsaa593cf:30376535
py29gd2263:30899288
c4g48928:30535728
azure-dev_surveyone:30548225
a9j8j154:30646983
962ge761:30959799
pythongtdpath:30769146
welcomedialogc:30910334
pythonidxpt:30866567
pythonnoceb:30805159
asynctok:30898717
pythontestfixt:30902429
pythonregdiag2:30936856
pyreplss1:30897532
pythonmypyd1:30879173
pythoncet0:30885854
pythontbext0:30879054
dsvsc016:30899300
dsvsc017:30899301
dsvsc018:30899302
pydisww2:30959801
a89i1917:30961429
7j2b6412:30964151
e3gdj431:30958358

Thanks for creating this issue! It looks like you may be using an old version of VS Code, the latest stable release is 1.86.2. Please try upgrading to the latest version and checking whether this issue remains.
Happy Coding!

/needsMoreInfo

Thanks for creating this issue! We figured it's missing some basic information or in some other way doesn't follow our issue reporting guidelines. Please take the time to review these and update the issue.
Happy Coding!

This issue has been closed automatically because it needs more information and has not had recent activity. See also our issue reporting guidelines.
Happy Coding!


Use local_inner_macros within macros where needed

I believe there are a few cases where this would help when a macro references itself.

This is actually discouraged according to the relevant documentation: https://doc.rust-lang.org/reference/macros-by-example.html#hygiene

This is intended primarily as a tool to migrate code written before $crate was added to the language to work with Rust 2018's path-based imports of macros. Its use is discouraged in new code.

Therefore, the code should instead prepend $crate:: in all of the relevant places.


Fixed #35113 -- Adding urls.py file while creating new app using startapp command

Ticket - #35113
Added urls.py-tpl file in conf/app_template.
This is my first PR and Ticket. Open for constructive comments and review.
Thanks!

Closing per ticket.

Closing per ticket.

What does it mean @felixxm

Check the ticket.


Clean up APIs

@hermet any reason why enums: Result/PathCommand/CanvasEngine/MempoolPolicy were not forced to be uint8_t like the others?

Probably, we can additionally include the PathCommand here, but there is no point in changing them because they are usually used as volatile values in most cases. 32 bits/64 bits are better to use in decent architectures. So it's more like the perf vs consistency problem.

Need to consider PathCommand to change or not. It breaks the C API efficiency.


Update configuration on page reload

Description
This is a bug fix where the API configuration changes are not reflected on the UI on page refresh.
Change to not memoize the configuration on the UI and make sure we trigger the GET settings API call each time we reload the page. This will ensure that any API configure changes made will reflect on the UI.
Details:

Using useState allows metricSettingsMap to be explicitly updated rather than memoized, making it a more reliable source of truth.
Updating metricSettingsMap in a useEffect ensures the latest settings are loaded whenever they change, such as on page refresh.
Adding metricSettingsMap as a dependency in the newOrReset useEffect triggers the function on each update, ensuring UI fields match the current settings.

Together, these changes ensure that metricSettingsMap reflects the latest settings on every page refresh, maintaining accurate UI state and addressing the original issue.
Testing
Tested on local by deploying OS with query insights and OSD with query insights dashboards. Verified that updating the settings via API is now reflected when we refresh the UI page.
Issues Resolved
Closes: #27
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

I think the issue is actually with not passing in window_size with memory enablement. Error message in console:
TopNQueries.tsx:174 Failed to retrieve settings: TypeError: Cannot read properties of undefined (reading 'match')
    at TopNQueries.tsx:165:1

Which is pointing to https://github.com/opensearch-project/query-insights-dashboards/blob/main/public/pages/TopNQueries/TopNQueries.tsx#L205. If this window_size is not passed, it errors out before setting enabled as true.


Delay slows down website

https://github.com/mdhiggins/ESP8266-HTTP-IR-Blaster/blob/9b5f617836af4d7a89bdf074e623e0d7e996970e/IRController/IRController.ino#L1405
What is the reason for this delay? The website needs really long to load. I reduced this delay to 10ms, that approves the website speed a lot.

improves of course...

Its just there to reduce power consumption, should only introduce at maximum a 200ms delay before the website responds, I'll do some testing to see if its interfering with the sendContent each loop though
That being said it can be safely removed if you don't want it there

I see no difference in website response time with or without the delay, it at most will create 200ms as expected, feel free to remove it if needed