[DISCUSSION] Making it easier to use DataFusion (lessons from GlareDB)

Is your feature request related to a problem or challenge?
I recently watched the Biting the Bullet: Rebuilding GlareDB from the Ground Up (Sean Smith) video from the CMU database series by @scsmithr. I found it very informative (thanks for the talk)
My high level summary of the talk is "we are replacing DataFusion with our own engine, rewritten from the the ground up". It sounds like GlareDB they are still using DataFusion as the new engine is not yet at feature parity
From my perspective, it seems that GlareDB's decision is a result of their judgement on the relative benefits vs estimated costs between

Developing a new engine by themselves (and the associated testing, maintenance, etc)
Working to integrate DataFusion / work with the community to help make it better

Of course, not every organization / project will have the same tradeoffs, but several of the challenges that @scsmithr described in the talk I think are worth discussing to make them better.
Here is my summary of those challenges:
Effort required / Regressions during upgrades
The general sentiment was that it took a long time to upgrade to DataFusion versions. This is something I have heard from others (@paveltiunov  for example from Cube). We also experience this at InfluxData
Also, he mentioned they had hit issues where queries that used to work did not after upgrade.
Possible Improvements

[ ] More testing via additional test coverage (it would be great to see some explicit investment in this area)
[ ] https://github.com/apache/datafusion/issues/13470
[ ] Discussion on being more deliberate with API changes / slowing down breaking
[ ] Discuss / document ways to make it easier for users (e.g. @jacksonrnewhouse mentioned keeping to the higher levels made upgrades a lot easier)

Dependency management
Glare DB uses Lance and delta-rs, which both use DataFusion, and currently this requires the version of DataFusion used by GlareDB to match the(he specifically cited https://github.com/delta-io/delta-rs/pull/2886 which just finally merged)
For what it is worth, @matthewmturner  and I hit the same thing in dft (see https://github.com/datafusion-contrib/datafusion-dft/pull/150)
Possible Improvements

I think the FFI work that @timsaucer  is working on (e.g. https://github.com/apache/datafusion/pull/12920 / https://github.com/delta-io/delta-rs/pull/3012) / some examples of how it can be used to integrate delta and iceberg and lance built with different DataFusion versions would be super helpful.

WASM support
I don't think he said explicitly that DataFusion couldn't do WASM, but it seemed to be implied
Thanks to the work from @jonmmease @waynexia and others, DataFusion absolutely be compiled to WASM (check out this cool example from @XiangpengHao: https://parquet-viewer.haoxp.xyz/) but maybe it needs to be better documented / explained in a blog

[ ] Blog about how to compile DataFusion for WASM??

Implicit assumptions in LogicalPlans
Another thing that was mentioned was the challenge of writing custom optimizer rules was challenging because there were implicit assumptions (e.g. that column names were unique)
Possible Improvements

[ ] Better document what those assumptions are
[ ] For example, https://github.com/apache/datafusion/issues/12736

SQL Features
Repeated column names came up as an example feature that was missing in DataFusion.
select * from (values (1), (2)) v(a, a)

Possible Improvements

[ ] I think @findepi is also thinking about this as part of  https://github.com/apache/datafusion/issues/12723

Distributed Planning and Execution
Planning:
The talk mentioned that the DataFusion planner was linear in the way it resolved references and the GlareDB system needed to resolve references from a remote catalog. Their solution seems to have been to fork the DataFusion SQL planner and make it async
Another approach that is taken by the SessionContext::sql Is:

Does  an initial pass through the parse tree to find all references (non async)
Then fetch all references (can be async)
Then does the planning (non async) with all the relevant references

I don't think this is particularly well documented
Possible Improvements

[ ] Add an example of implementing a remote / async catalog

Execution:
The talk mentioned several times that GlareDB runs distributed queries and found it challenging to use a different number of threads on different executors (it sounds like maybe they split the ExecutionPlan, which already has a target number of partitions baked in). It sounds like their solution was to write a new scheduler  / execution engine that didn't have the parallelism baked in
Another potential way to achieve a different threads per execution node  is to do the distribution at the LogicalPlan level and then run the physical planner on each sub part of the LogicalPlan.
Possible Improvements

[ ] Maybe we could document that better / show an example of how to split / run a distributed plan

Describe the solution you'd like
No response
Describe alternatives you've considered
No response
Additional context
No response

Thanks for opening up this issue. I'll follow up with a longer-form comment describing more of what we were facing and ultimately why we switched off.
But want to leave a quick comment on how this feedback was delivered. I think the talk is very easy to be seen as a bit toxic/inflammatory, and that's something I could've handled better. It should have been less derisive and more constructive. Running a startup and trying to hit tight deadlines is incredibly draining. And I think the frustration/exhaustion just boiled over a bit.
I think DataFusion is a great project with the unique goal of building a composable engine. It's pretty rare to see in this space and the approach taken here has been pretty innovative.

But want to leave a quick comment on how this feedback was delivered. I think the talk is very easy to be seen as a bit toxic/inflammatory, and that's something I could've handled better. It should have been less derisive and more constructive. Running a startup and trying to hit tight deadlines is incredibly draining. And I think the frustration/exhaustion just boiled over a bit.

Thank you for saying that.
I didn't think the tone of your talk was derisive or toxic or inflammatory. I think you brought up several very valid points, and I very much appreciate the need to innovate quickly in a startup and the near-term slowdown that results in working with a larger existing codebase / community.
While of I probably would make different tradeoffs (like spending time on this post trying to make DataFusion better 😉  ) I totally understand the right tradeoffs are different for different teams.
I wish you nothing but the best at GlareDB. And of course, should you ever change your mind or perhaps DataFusion has improved in some areas, we'll be waiting to welcome you back to the community

@scsmithr In your follow up I think it would be useful to know if there is anything the DataFusion project could do better that would have made you more likely to contribute the necessary improvements back as opposed to starting from scratch.

thank you @alamb for the list, this is great! I know GlareDB's perspective is important and it feels like "lost customer deal" for an OSS project. As with all deals, it's equally important to learn from those lost and also from those retained.
For example, my perspective from working on SDF is

leaky DF SQL semantics (DF implements its own dialect of SQL and not everyone wants to get exactly that), including coercions https://github.com/apache/datafusion/issues/12723

clean separation between DF frontend (dialect) and internals (dialect-free)

limited type system (which for SDF is OK if we "compile/lower to DF LP", but things would be simpler if we could "just be DF LP")

logically equivalent distinct physical types https://github.com/apache/datafusion/issues/12622
no extension types https://github.com/apache/datafusion/issues/12644

better internal LP design (https://github.com/apache/datafusion/issues/12604, and also for https://github.com/apache/datafusion/issues/13476, https://github.com/apache/datafusion/issues/6543)
better test coverage (eg https://github.com/apache/datafusion/issues/13470)
(perhaps some other i don't remeber right now)

having said the above, DataFusion is a GREAT library to build on.

Choosing DataFusion
We chose to use DataFusion for the base of our product ~June 2022 and have kept up with it until earlier this year.
When deciding, we looked at:

Community: DataFusion seemed to have a quite a few contributors and that didn't look like it was slowing down. And seeing the investment from Influx was a confidence builder.
Performance: At the time, DataFusion was already pretty fast, and again, it just felt like it'd be getting better over time.
Extensibility: The big thing for us, it was really cool to see that almost every part could be extended and customized.

The main alternative we looked at was DuckDB. But opted to go for it since it was written in C++ (not a bad thing, just I was much more familiar with Rust and was focused on building a Rust team) and it seemed a bit less extensible than DataFusion for our needs.
And as a mentioned in the talk, choosing DataFusion got us to a POC very quickly and let us build out the rest of the features we wanted.
Core challenges
Dependencies
Huge challenge for us. As a startup, we wanted to try to bring in libraries instead of trying to write our own. And since we were billing ourselves as a database to query across data sources, bringing in libraries like delta-rs and lance with already written TableProviders for those formats seemed like a no-brainer.
However trying to keep all these in sync with the right version of DataFusion (and Arrow) was incredibly challenging and time consuming. Sometimes there were pretty major blockers for either of those to upgrade. Some folks on our team helped out with a few upgrades (e.g. https://github.com/delta-io/delta-rs/pull/2249), but some upgrades ended up taking a bit a time away from building the features we needed.
Did we have to upgrade? No, but we chose DataFusion not for where it is today, but where it'll be in the future. And delaying the upgrades meant we would just be stacking up the incompatibilities and missing out on fixes/features that were going in.
This issue only started to crop up when we decided to depend on delta-rs & lance, before then we didn't really have dependency issues.
Upgrades
This goes hand-in-hand with our dependency challenges. But I want to be more specific around upgrading DataFusion.

More testing via additional test coverage (it would be great to see some explicit investment in this area)

I accept that bugs will be introduced. It's software, it happens. The real challenge was actually upgrading to get the bug fixes because of the deps...

Discussion on being more deliberate with API changes / slowing down breaking

I actually don't really care about API breakages if there's a clear path to getting the equivalent functionality working.
If something's bad, change it/break it and make it better. As an end user, this is fine. "Better" is subjective and depends on the use case.
I'd sum this up as upgrades were fine, our challenges were with upgrades + upgrading dependencies.
Component composability
We originally chose DataFusion for the composability, and I went in with the idea that I'd be able to have all components within DataFusion be composable. I tried to shoe horn that ideal with our early versions of GlareDB with mixed success.
For example, I can't just have an Optimizer struct configured with some parameters and rules, I need to go through a SessionContext to have the optimizer work right. For example, we had a bug where select now() would return the wrong time because the optimizer was was using a field provided by the context for replacing the now() call with constant. See: https://github.com/GlareDB/glaredb/issues/1427
There were a few other issues where attempting to use the pieces separately ended up biting us because of these implicit dependencies. I really wanted to avoid the SessionContext so that we could have fine-grained control over planning and execution, but we were forced into using the SessionContext because the optimizer wouldn't work right for certain queries, or and ExecutionPlan would read a configuration var from the TaskContext that could only be set through the SessionContext and have it be properly threaded down.
Essentially it felt like we had to depend on the SessionContext in order to use anything with confidence of it working as expected. Either because things were designed that way, or because we had limited visibility (pub (crate)) to the actual fields/types.
This has gotten better over time (e.g. the OptimizerConfig would have solved our above select now() problem), but we've also had changes go the other way the increased dependence on the SessionContext. One of our earliest issues was the change to FileScanConfig removing the ability to just provide an ObjectStore (https://github.com/apache/datafusion/pull/2668). Since we're building a multi-tenant database, we want very complete control over how ObjectStores are constructed and how they're used since they'll typically be unique to the session. The above change forced how we managed object stores if we wanted to use the file scan features from DataFusion. This has also introduced some weirdness when more "dynamic" object stores are needed, e.g. delta-rs needs to generate unique urls for object stores they create just to store them on the context: https://github.com/delta-io/delta-rs/blob/main/crates/core/src/logstore/mod.rs#L257-L265.
I'd summarize this as: We wanted to use all of DataFusion's features, but in a way where we could control how those features we're used. I want full control over configuring the optimizer, or the listing table, or ... But in many cases, that configuration can only happen with the use of SessionContext.
A suggestion might be to open up explicitly configuring components in DataFusion without the use of a SessionContext, and just have the SessionContext provide the easy to use interface for everything.
Features (misc)
WASM

I don't think he said explicitly that DataFusion couldn't do WASM, but it seemed to be implied

I didn't mean to imply it, just that it's not something actively tested/developed for in DataFusion. I can't recall the exact issue, but late last year (2023) I was working on getting stuff running in the browser and was facing a panic since something was blocking.
There's a lot of considerations needed when bringing in dependencies when trying to compile for WASM, and most of our issues around that were just we didn't have a clean split with what works with WASM vs what doesn't. That's not a DataFusion issue.
Column naming/aliasing

Repeated column names came up as an example feature that was missing in DataFusion.
select * from (values (1), (2)) v(a, a)

This came up quite a bit for us earlier since we would have folks try out joins across tables with very similar schemas (e.g. finding the intersection of users between service "A" and service "B") and sometimes those queries would fail due to conflicting column names, even when the user wasn't explicitly selecting them.
This has gotten better in DataFusion, but I don't think DataFusion's handling of column names (and generating column names) is good. There's a lot of code to ensure string representations of expressions are the same across planning steps, and it's very prone to breaking. I did try to add in more correlated subquery support but stopped because frankly I found the logical planning with column names to be very unpleasant.
Async planning

Another approach that is taken by the SessionContext::sql Is:

Does an initial pass through the parse tree to find all references (non async)
Then fetch all references (can be async)
Then does the planning (non async) with all the relevant references

I don't think this is particularly well documented

Yes, this is what we needed. At the time, we just forked the planner since it was easier to make changes that way (since we were also adding table functions for reading from remote sources).
Execution

The talk mentioned several times that GlareDB runs distributed queries and found it challenging to use a different number of threads on different executors (it sounds like maybe they split the ExecutionPlan, which already has a target number of partitions baked in). It sounds like their solution was to write a new scheduler / execution engine that didn't have the parallelism baked in

Yes, we wanted to independently execute parts of the queries across heterogeneous machines.
We looked Ballista quite a bit, but ultimately when with a more stream-based approach to try to fit in better with how DataFusion executes queries. There's a high-level comment here about what we were trying to accomplish (split execution across a local and remote machine) but the code itself ended up being quite complex.
I don't think it makes sense for DataFusion to try to cater to this use case, but this ultimately ended up being a reason why we moved away and is very central to the design of the new system.

Happy to go deeper in any of this.

@scsmithr In your follow up I think it would be useful to know if there is anything the DataFusion project could do better that would have made you more likely to contribute the necessary improvements back as opposed to starting from scratch.

This is honestly pretty hard to answer.
I think a lot of this is just circumstance and needing to move very quickly. I felt like there were areas in DataFusion that I personally wanted to improve and work on, but I ultimately felt like trying to make those improvements would take way too long relative to the time I have.
We chose to build on DataFusion in order to move quickly. But ended up being a bit encumbered with dep upgrades, and the context switching between our code base upstream DataFusion definitely had a hit on productivity.

I can relate to (compared with GreptimeDB) the situation & challenges from @scsmithr's share: the dependency, a bit of headache upgrade procedure etc. I'd like to share some of my experiences:
For the consideration of workload, we choose to upgrade DataFusion periodically instead of continuously (like Ubuntu vs. Arch). Hence (1) related dependencies are locked before the next upgrade and (2) need to handle a bunch of accumulated API changes and do a regression test. Since we rarely long for a new API from Arrow eagerly, the first point is acceptable for us. But 2 in contrast, can be classified as the most painful thing of the entire experience 🤣 I tried to conclude this, but it turns out the breaking change of existing API is not the root cause, as they are always explicit and can be solved easily, especially we (the DataFusion) will #[deprecated] an API for a while before removing it. However, those non-breaking changes at the API level are painful: they are implicit so you won't notice them until something went wrong. E.g.: a new property interface on the plan and some optimizer rules using this property to rewrite the plan.
I haven't found a good solution or suggestion for this problem. I am not even sure if it's possible to maintain all those complex connections among so many plans and optimizers. Given DataFusion is highly extensible and allows user to define their own plan, type or rule etc, this becomes harder to handle. We can't write tests for things that don't exist..
For execution, I tried an approach (slides here https://github.com/apache/datafusion/discussions/10341#discussioncomment-10110273) that rewrote the plan to enable execution across multiple nodes, which seems to have a similar interface to the RemotePhysicalPlanner from your link. Though this is not yet completed and is still under (inactive 😢) development, it looks viable to me.

Blog about how to compile DataFusion for WASM??

Willing to draft one. Including some small lessons learned from making a Rust-WASM object and the API consideration. I wrote a few notes but never had the motivation (lazy, in other words 🙈) to organize them.

I have felt the pain points of the version upgrades. I mentioned this in the discord server, but one thing I think we can do that will lessen this is to push hard to get the datafusion-python upgrade PR through as fast as we can once a release candidate is ready for datafusion. Then we can document all the changes we had to make for it and add them to the release notes. It would be good to have a page similar to what pyo3 does with their migration guide. I know this might slow down the release process but I think it would be a good thing to do since part of our goal is to have datafusion-python expose most of datafusion. It won't catch everything, so we might also want to ask any PRs with breaking API changes to document what users need to do for migration.

However, those non-breaking changes at the API level are painful: they are implicit so you won't notice them until something went wrong.

Agree with what @waynexia mentioned, when I upgraded datafusion in HoraeDB a few months ago, it is really painful due to the implicit changes.
Finally after spending many time to debug, I found it is caused by the implicit change of TableProvider::scan, columns in filter not included in the pushing down projection anymore...
I think maybe we should make the similar important changes explicit, otherwise it may be so hard to find what was wrong in the complex system built on datafusion.

I also relate with the pain/anxiety of updating DataFusion due to changes in implicit logic.
It's not really captured by semver, but it would be nice if there were a distinction between breaking changes that simply require fixing compilation errors in a straightforward way, vs those that are changes in behavior without API changes.

On Dependency Management I have a suggestion that I think could help but would take actual and ongoing work on the DF communities' part.
I would suggest that we file tickets as part of every release to test DF with latest versions of common external dependencies (datafusion-python, iceberg, lance, delta, etc) as part of the gating criteria for a release. Perhaps this would be as simple as changing the DF version in those projects and running their test suite. Any blockers that are found in DF have tickets filed and are fixed, other blockers in the respective projects have tickets filed in those projects

I have felt the pain points of the version upgrades. I mentioned this in the discord server, but one thing I think we can do that will lessen this is to push hard to get the datafusion-python upgrade PR through as fast as we can once a release candidate is ready for datafusion. Then we can document all the changes we had to make for it and add them to the release notes. It would be good to have a page similar to what pyo3 does with their migration guide. I know this might slow down the release process but I think it would be a good thing to do since part of our goal is to have datafusion-python expose most of datafusion. It won't catch everything, so we might also want to ask any PRs with breaking API changes to document what users need to do for migration.

Spark provides an upgrade guide for major new versions. Perhaps we could do the same?
Any PR that is a breaking change should also include updates to the upgrade guide for the next release.
Upgrading our own subprojects (Ballista, Comet, DF Python, DF Ray) as part of the DataFusion release process makes a lot of sense to validate that the upgrade guide is complete.

It's not really captured by semver, but it would be nice if there were a distinction between breaking changes that simply require fixing compilation errors in a straightforward way, vs those that are changes in behavior without API changes.

I think this is an astute observation:
Figuring out how to flag PRs that make changes that are not "breaking" in the API sense but are breaking in some semantic sense.

I would suggest that we file tickets as part of every release to test DF with latest versions of common external dependencies (datafusion-python, iceberg, lance, delta, etc) as part of the gating criteria for a release. Perhaps this would be as simple as changing the DF version in those projects and running their test suite. Any blockers that are found in DF have tickets filed and are fixed, other blockers in the respective projects have tickets filed in those projects

I think this would be a great idea, and I often try to do exactly this (as a sanity check) with arrow-rs releases or sqlparser-rs releases (e.g. here) before I release them to crates.io

Upgrading our own subprojects (Ballista, Comet, DF Python, DF Ray) as part of the DataFusion release process makes a lot of sense to validate that the upgrade guide is complete.

Maybe just doing this

😢

I am currently upgrading DataFusion as well.
Besides some DF upgrading hassle, the main work for us seems the tonic upgrade (to 0.12) which "forces" upgrading to 1.0 ecosystem (warp doesn't support it, so this requires some code juggling).

Besides some DF upgrading hassle, the main work for us seems the tonic upgrade (to 0.12) which "forces" upgrading to 1.0 ecosystem (warp doesn't support it, so this requires some code juggling).

BTW what we have done in InfluxDB (temporarily) is to fork arrow-rs and downgrade the tonic upgrade. This let us decouple upgrading DataFusion from the tonic upgrade. You can see what I did here

https://github.com/influxdata/arrow-rs/pull/4

Then we plan/hope to migrate to the latest hyper (1.0) incrementally

I didn't mean to imply it, just that it's not something actively tested/developed for in DataFusion. I can't recall the exact issue, but late last year (2023) I was working on getting stuff running in the browser and was facing a panic since something was blocking.
There's a lot of considerations needed when bringing in dependencies when trying to compile for WASM, and most of our issues around that were just we didn't have a clean split with what works with WASM vs what doesn't. That's not a DataFusion issue.

About WASM, I’d like to share some experience from working on https://github.com/apache/datafusion/pull/10745#issuecomment-2143911214. I think datafusion-core works fine, but some extension crates (e.g., object_store) might cause conflicts. Perhaps we could document this as a potential issue if it hasn’t been resolved yet. (I’m not entirely sure about the current status, though. 🤔)

For the object_store specific problem, it doesn't have wasm support so far as I know. I've used opendal as a workaround in https://github.com/datafusion-contrib/datafusion-wasm-bindings

R.e. WASM32

Arrow support for 32-bit architectures - https://github.com/apache/arrow-rs/issues/6681
Object Store support for 32-bit architectures - https://github.com/apache/arrow-rs/issues/5351
Object Store support for WASM32 - https://github.com/apache/arrow-rs/issues/6818

Currently support for these architectures is untested, has known issues, and I would not rely on it in a production setting, help is very welcome to improve this situation. The first step is probably working out what is broken, and getting some sort of CI setup so that progress can be made on improving this situation.

Besides some DF upgrading hassle, the main work for us seems the tonic upgrade (to 0.12) which "forces" upgrading to 1.0 ecosystem (warp doesn't support it, so this requires some code juggling).

BTW what we have done in InfluxDB (temporarily) is to fork arrow-rs and downgrade the tonic upgrade. This let us decouple upgrading DataFusion from the tonic upgrade. You can see what I did here

arrow 53.2.0 with downgraded tonic / prost influxdata/arrow-rs#4

Then we plan/hope to migrate to the latest hyper (1.0) incrementally

That is a great point, let me see if we can do that as well.

I often need to play with DataFusion API (what the output for input and etc) and if it will be compiled to WASM we could create a website like Rust Playground

I filed a few tickets for some of the documentation / follow on items listed above:

https://github.com/apache/datafusion/issues/13714
https://github.com/apache/datafusion/issues/13715


symfit package runtime error with fit.py module

This issue relates to a run-time error raised in the symfit package "fit.py" routine.  Here is the traceback:
Traceback (most recent call last):
File "C:\Users\Gary\PYfun\SYMFIT~1\SYMFIT~1.DIS\symfitexample.py", line 38, in
File "C:\Users\Gary\PYfun\SYMFIT~1\SYMFIT~1.DIS\symfit\core\support.py", line 427, in wrapped_func
File "C:\Users\Gary\PYfun\SYMFIT~1\SYMFIT~1.DIS\symfit\core\fit.py", line 394, in init
File "C:\Users\Gary\PYfun\SYMFIT~1\SYMFIT~1.DIS\symfit\core\support.py", line 427, in wrapped_func
File "C:\Users\Gary\PYfun\SYMFIT~1\SYMFIT~1.DIS\symfit\core\fit.py", line 91, in init
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Unfortunately, even a small demo program requires an extensive compilation to reveal the bug.  For a demo program, I just used the example given with the symfit documentation for a fourier series fit. The code can be found here:
https://symfit.readthedocs.io/en/stable/examples/ex_fourier_series.html
from symfit import parameters, variables, sin, cos, Fit
import numpy as np
import matplotlib.pyplot as plt
def fourier_series(x, f, n=0):
"""
Returns a symbolic fourier series of order n.
:param n: Order of the fourier series.
:param x: Independent variable
:param f: Frequency of the fourier series
"""
# Make the parameter objects for all the terms
a0, *cos_a = parameters(','.join(['a{}'.format(i) for i in range(0, n + 1)]))
sin_b = parameters(','.join(['b{}'.format(i) for i in range(1, n + 1)]))
# Construct the series
series = a0 + sum(ai * cos(i * f * x) + bi * sin(i * f * x)
                 for i, (ai, bi) in enumerate(zip(cos_a, sin_b), start=1))
return series

x, y = variables('x, y')
w, = parameters('w')
model_dict = {y: fourier_series(x, f=w, n=3)}
print(model_dict)
Make step function data
xdata = np.linspace(-np.pi, np.pi)
ydata = np.zeros_like(xdata)
ydata[xdata > 0] = 1
Define a Fit object for this model and data
fit = Fit(model_dict, x=xdata, y=ydata)
fit_result = fit.execute()
print(fit_result)
Plot the result
plt.plot(xdata, ydata)
plt.plot(xdata, fit.model(x=xdata, **fit_result.params).y, ls=':')
plt.xlabel('x')
plt.ylabel('y')
plt.show()
My python and nuitka version:
(myenv) C:\Users\Gary\PYfun\Symfitexample\symfitexample.dist>python -m nuitka --version
<IP_ADDRESS>
Commercial: None
Python: 3.9.7 (default, Sep 16 2021, 16:59:28) [MSC v.1916 64 bit (AMD64)]
Flavor: Anaconda Python
Executable: C:\Users\Gary\anaconda3\envs\myenv\python.exe
OS: Windows
Arch: x86_64
WindowsRelease: 10
Most of the packages I use were loaded through the anconcda channel.  The symfit package was loaded through conda-forge.
The command I used to start the nuitka compile:
python -m nuitka symfitexample.py --static-libpython=no --standalone --enable-plugin=numpy --enable-plugin=pyqt5
On my modest laptop development system this short script took a good fraction of the day to build and resulted in  2.5GB .build folder and a 1.2GB .dist folder.
I get very nearly identical errors in my application as are generated with this example.

This is working these days.


Use json format to store data

:tada: This PR is included in version 1.0.0 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket:


Polish-Perl-6-First-Steps-Experience: improve https://perl6.org/downloads/

Hi,
i read:
https://perl6.party/post/A-Call-To-Action--Polish-Perl-6-First-Steps-Experience
and would like to give some feedback:
The short version is: "$PATH setup needs to be documented better"
The long version:
My first steps were:
Reading https://perl6.org/
clicked on "Download Rakudo Perl 6"
wondered "oh its a build from source"
followed "A quick start for Linux/Mac/BSD/Mingw etc. follows:"
...
make install
So far so good. Then I tried to use it:
# /opt/rakudo-star-2018.04/bin/perl6
#  ok that worked! I the setup a $PATH variable containing /opt/rakudo-star-2018.04/bin
# then I tried to install a perl6 module I wrote some time ago
$ zef
# not found ??

I then read https://rakudo.org/files/star/source linked from https://perl6.org/downloads/ found the
export PATH.... statement and pasted it into my shell.
echo "export PATH=$(pwd)/install/bin/:$(pwd)/install/share/perl6/site/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
Still no fun. The --prefix /opt/rakudo-star-2018.04 was not taken into account.
There seem to exists the following directories named 'bin'
...bin/rakudo-star-2018.04/bin
...bin/rakudo-star-2018.04/share/perl6/bin
...bin/rakudo-star-2018.04/share/perl6/site/bin
...bin/rakudo-star-2018.04/share/perl6/vendor/bin
Basically I would expect that the install instructions guide me through the whole process, so that I can just type 'perl6, zef, etc' afterwards in a shell.
Now I need to find a guide howto transfer the build process of my module form panda to zef.....

When you install Rakudo Star it prints instructions at the end telling you exactly what needs to be in your PATH so it already behaves how you want!


Classic portal no longer available "storsimple-8000-move-azure-portal-faq"

Please update the article, because most of the questions are irrelevant, because classic portal no longer available and operations can't be done in it.
I'm about questions like "I have multiple StorSimple Managers running in the classic portal." or "I initiated the migration of my service to the new Azure portal. Should I delete the StorSimple Manager from the classic portal?"

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 1db5b17e-1869-c830-22c4-b9242dbe517b
Version Independent ID: 5826118d-6f93-b065-b634-03ee23053893
Content: Move from classic to Azure portal FAQ
Content Source: articles/storsimple/storsimple-8000-move-azure-portal-faq.md
Service: storsimple
GitHub Login: @alkohli
Microsoft Alias: alkohli

@SychevIgor Thanks for your feedback! This article will not be updated as it was written to address a specific need - answer questions during migration of customers to Azure portal from classic portal. Instead I will retire this article as all the StorSimple customers have now migrated.

#in-progress

@SychevIgor  This article is now deleted as it is no longer relevant. Migration to new Azure portal is complete. The links to article will now redirect to the StorSimple documentation page. The article was deleted via PR https://github.com/MicrosoftDocs/azure-docs-pr/pull/40896. This PR is now merged, changes will be live at the next publish cycle. Thanks for your patience!
#please-close

@SychevIgor We will now proceed to close this thread. If there are further questions regarding this matter, please reopen it and we will gladly continue the discussion.


Add functionality to page teams

Create a keyword handler that will allow you to page specific teams using PagerDuty during an incident.

Fixed in #69


Improve handling of generic C# types

Improve handling of generic C# types

Create CSharpScript for generic C# types.

ScriptPathAttributeGenerator registers the path for the generic type definition.
ScriptManagerBridge lookup uses the generic type definition that was registered by the generator.
Constructed generic types use a virtual csharp:// path so they can be registered in the map and loaded as if there was a different file for each constructed type, even though they all share the same real path.

Thanks so much to @Delsin-Yu for the idea.

This allows getting the base type for a C# type that derives from a generic type.

Shows base scripts in the Add Node and Create Resource dialogs even when they are generic types.

get_global_class_name implementation was moved to C# and now always returns the base type even if the script is not a global class (this behavior matches GDScript).

Create CSharpScript::TypeInfo struct to hold all the type information about the C# type that corresponds to the CSharpScript, and use it as the parameter in UpdateScriptClassInfo to avoid adding more parameters.

The fields of the struct, as well as other CSharpScript fields, are also now documented :slightly_smiling_face:.

Fixes https://github.com/godotengine/godot/issues/87877

There's also a little bit of background on these previously merged PRs:

https://github.com/godotengine/godot/pull/55597.
https://github.com/godotengine/godot/pull/70511.

I met the exception when selecting a node with generic type inherited:
  C:/Users/zaevi/source/Godot/godot-source/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs:113 - System.IO.IOException: 文件名、目录名或卷标语法不正确。 : 'C:\Users\zaevi\source\Godot\temp\crash_test\csharp:\generic\Base.cs:Base`1[System.Int32].cs'
     at System.IO.FileSystem.GetAttributeData(String fullPath, Boolean returnErrorOnNotFound)
     at System.IO.File.GetLastWriteTime(String path)
     at GodotTools.Utils.File.GetLastWriteTime(String path) in C:\Users\zaevi\source\Godot\godot-source\modules\mono\editor\GodotTools\GodotTools\Utils\File.cs:line 25
     at GodotTools.Inspector.InspectorPlugin._ParseBegin(GodotObject godotObject) in C:\Users\zaevi\source\Godot\godot-source\modules\mono\editor\GodotTools\GodotTools\Inspector\InspectorPlugin.cs:line 27
     at Godot.EditorInspectorPlugin.InvokeGodotClassMethod(godot_string_name& method, NativeVariantPtrArgs args, godot_variant& ret) in C:\Users\zaevi\source\Godot\godot-source\modules\mono\glue\GodotSharp\GodotSharpEditor\Generated\GodotObjects\EditorInspectorPlugin.cs:line 156
     at GodotTools.Inspector.InspectorPlugin.InvokeGodotClassMethod(godot_string_name& method, NativeVariantPtrArgs args, godot_variant& ret) in C:\Users\zaevi\source\Godot\godot-source\modules\mono\editor\GodotTools\GodotTools\Godot.SourceGenerators\Godot.SourceGenerators.ScriptMethodsGenerator\GodotTools.Inspector.InspectorPlugin_ScriptMethods.generated.cs:line 50
     at Godot.Bridge.CSharpInstanceBridge.Call(IntPtr godotObjectGCHandle, godot_string_name* method, godot_variant** args, Int32 argCount, godot_variant_call_error* refCallError, godot_variant* ret) in C:\Users\zaevi\source\Godot\godot-source\modules\mono\glue\GodotSharp\GodotSharp\Core\Bridge\CSharpInstanceBridge.cs:line 24

Seems it tries to check LastWriteTime using that virtual path.

@zaevi Interesting, it doesn't throw in Linux so I didn't notice. Should be fixed now.

I'm having weird behaviours with export updates + the error I'm talking about above. See video attached.
https://github.com/godotengine/godot/assets/437025/4f89f9e6-e957-49f5-91f4-c8ae29de5a35

I'm having weird behaviours with export updates + the error I'm talking about above. See video attached.
godot.windows.editor.dev.x86_64.mono_6ur3hBmru1.mp4

Could be caused by the cache. It's ok after I delete the .godot folder (and rebuild), but updating the exported property and reloading the project throws the exception again.

@paulloz Thanks, I can reproduce following the steps in the video. I'm having the same behavior in 4.2.1-stable. The inspector plugin does not seem to be called at all when modifying generic scripts, but it doesn't seem to be introduced by this PR.
I'm also able to reproduce the other error you mentioned, I don't know why I didn't encounter it before.

The inspector plugin does not seem to be called at all when modifying generic scripts, but it doesn't seem to be introduced by this PR.

You are right about the inspector plugin, but the exports themselves should appear after a build. They currently do on master:
https://github.com/godotengine/godot/assets/437025/0de8d69e-a48a-4276-a006-6b6291794b32

We would not be able to update the exports anyway, since it's a generic type definition and we can't call C# methods on an unbound generic.

But at that point the generic type is fully bound, since it's the once in the class hierarchy of a valid node.

You are right about the inspector plugin, but the exports themselves should appear after a build. They currently do on master

Oh, you are right. I feel like I tested this and it wasn't working. Thank you for testing.

But at that point the generic type is fully bound, since it's the one in the class hierarchy of a valid node.

I mean the empty CSharpScript with the path res://Foo.cs, not the CSharpScript with the virtual path csharp://Foo.cs:System.String.cs that is part of the Bar hierarchy.
I have checked and it seems _update_exports is never called on Foo<string> because AddScriptBridge returns false since it can't find the virtual path in the _pathTypeBiMap at this point of the reloading. This is probably because of the reload order, Foo<string> comes first since it's the base script but the virtual path won't be added until we construct it when reloading Bar which comes afterwards. I'm starting to think the complexity of these virtual paths may be too high.

Back to the reloading order again... Is it possible to somehow refractor the reloading logic to ensure this editor reserialization call comes after a complete iteration of to_reloads? This will remove the need to bother with script reloading order any more.

Is it possible to somehow refactor the reloading logic to ensure this editor reserialization call comes after a complete iteration of to_reloads?

That sounds like it require drastic changes to the reload logic which risk introducing bugs, I'm not sure it's worth doing such a big change since we'll be moving away from scripts in the future.

the exports themselves should appear after a build. They currently do on master

I was curious why it was working in master since we also don't have a path to the script there and found out that scripts without paths actually go through a different path when reloading assemblies.
So I made scripts with csharp:// paths be reloaded in the same way (as if they had no path) and it seems the exports update now.

That sounds like it require drastic changes to the reload logic which risk introducing bugs, I'm not sure it's worth doing such a big change since we'll be moving away from scripts in the future.

@raulsntos
Could you, please, elaborate a bit on "we'll be moving away from scripts in the future" ? :)
I'm very interested on the future of C# in Godot.
Also if there's any roadmap for C# features in the future, could you or anyone point me the link(s) ?
Thank you.


moved

Report malware or abuse
Please fill out the form to report malware or abuse in a package to the PlatformIO team.
The PlatformIO team will review the report and act accordingly. In cases where malware or abuse is confirmed, the package will be removed and the namespace will be blocked.
Sensitive information should be sent to<EMAIL_ADDRESS>included this issue link.
Please note that this report goes to the PlatformIO team for triage, not the package maintainer. To report bugs or vulnerabilities in a package please contact the maintainer directly.
Package information

Package name: viralink/Viralink_Arduino_SDK
Package version: all of them
Package link: https://registry.platformio.org/libraries/viralink/Viralink_Arduino_SDK

Description of vulnerability
we no longer maintain and develop this package and moved to new one https://registry.platformio.org/libraries/viralinkio/ViraLink-MQTT-Client please remove this

Thanks, the package has been deleted.


Pass platform specific find flags for executables (needed by darwin)

Introduces findExecutablesFlags as a variable which can be used to customize
the parameters for platform. So far used for darwin because it uses a find
which does not support "-perms /0100" whereas cygwin does not support "-perms
+0100" anymore.
This is inspired by the suggestion in https://github.com/NixOS/nixpkgs/pull/9603#issuecomment-137456599
It should solve the issue https://github.com/NixOS/nixpkgs/issues/9044
Never worked with these bits of nixpkgs so far, need some hint if this goes into the right direction or is fully off ;-)

Also this needs to be rebased on the staging branch, since this will rebuild everything.

@vcunat

Actually, now that I thought more about it, maybe it's better to make this more focused and only solve the stdenv related problem without messing up any packages, guess adjusting packages is afterwards easy, since they should not cause mass rebuilds.

Closing this, going to create a new pull request which targets staging.
Just for the record: Found out that find in packages can already come out of the findutils derivation, so it's not the darwin one and can work without the change.


Remove bounds but keep the pan functionality

How can I remove the bounds - i mean that the user will not be able to play with the image and move the image between the white spaces, and the image will be at the middle or take the div place
I m using simple image url
In addition I'd like to keep the ability to use the pan with the mouse
thx for amazing library again

I'm not quite sure what you're asking for.  Or do you mean you don't want them to drag it at all when it's zoomed out? Or do you mean you want less white space to appear around the image when it's zoomed out?


Issue 242 directmention documentation

Summary
Fixes #242. Updates docs with example of directMention and further details.
Requirements (place an x in each [ ])

[X] I've read and understood the Contributing Guidelines and have done my best effort to follow them.
[X] I've read and agree to the Code of Conduct.

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

But I think a better home for the rest may be in the reference documentation, which could explicitly list and explain a variety of built-in middleware (including directMention()).

I agree with this.
@andrewdietrich If you are still interested in working on this and you're fine to move this (and other built-in middleware too if possible..), it'd be appreciated 🙇


allow buffer switch to last

When using with ctag, only using bw and bn is not enough

Hi bro! I feel like we have the same idea, but it's kind of fuzzy can you explain it more clearly?
Btw, I'm porting this plugin to Lua, so if you have some Lua knowledge, maybe can you join me later after I finish rewriting the plugin? I have some ideas (I think you're implementing 1 of them) but I don't want to implement them using VimL.

Here is my config.
nmap <leader>1 <Plug>BuffetSwitch(1)
nmap <leader>2 <Plug>BuffetSwitch(2)
nmap <leader>3 <Plug>BuffetSwitch(3)
nmap <leader>4 <Plug>BuffetSwitch(4)
nmap <leader>5 <Plug>BuffetSwitch(5)
nmap <leader>6 <Plug>BuffetSwitch(6)
nmap <leader>7 <Plug>BuffetSwitch(7)
nmap <leader>8 <Plug>BuffetSwitch(8)
nmap <leader>9 <Plug>BuffetSwitch(9)
nmap <leader>0 <Plug>BuffetSwitch(0)
nmap <leader>] <Plug>BuffetNext
nmap <leader>[ <Plug>BuffetPrev

When I call BuffetSwitch(0), let the buffer switch to the last one.
The BuffetNext let buffer switch to next index in buffer_ids.
Sometime i use :bp or :bn not goto correct index of the buffer. So I add BuffetNext And BuffetPrev


Add possibility to make new branches in web interface

Gitea version (or commit ref): commit c3aaf5eafd91b881ca67ab51e0cc2fd17a5b7921
Database (use [x]):

[ ] PostgreSQL
[ ] MySQL
[ ] MSSQL
[X] SQLite

Description:
There is the possibility to make a commit with some changes but there are no the possibility to make a new branch. The equivalent to
git checkout -b new_branch_name
Adding this feature will case changes only it templates and adding new js handler because all we need at backend is in the code now.
This is new look of branch in branches page:

This is new form for setting name of new branch:

You can create a branch from the UI, however there is no button on the branches page.
Are you intending for this issue to be a feature request for the latter?

I can send pull request with a code I recently have written.


Removing unnecessary switch

Simplify this method by removing an unnecessary switch/case

This is done intentionally. It improves performance and readability of stack traces.

I think it's done on purpose for perfomance

See #12120 which was merged for L5.3, which is even faster.

@barryvdh Cool! Php 5.6+, right?

We already made this change in 5.3.


stable diffusion malloc error

mlx seemed to install fine but I tried the stable diffusion example and keep getting this:
134217728 bytes seems small, there should not be a problem allocating only ~134MB memory, the machine has 8GB RAM & ~4GB free. It's an Apple M2 Mac mini (running headless & connected to via VNC, could that cause issues?),
Or am I misunderstanding something basic, does this need an M2 Pro or something? Though it does go through all the (default) 50 steps before failing
I ran the MLX unit tests and they seemed to run fine, said '154 tests ran, 4 skipped'
(foo) david@Davids-Mac-mini stable_diffusion % python txt2image.py "A photo of an astronaut riding a horse on Mars." --n_images 1 --n_rows 1
/Users/david/mlx/foo/lib/python3.9/site-packages/urllib3/__init__.py:34: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
  warnings.warn(
100%|
 [00:00<?, ?it/s]libc++abi: terminating due to uncaught exception of type std::runtime_error: [malloc_or_wait] Unable to allocate 134217728 bytes.
zsh: abort      python txt2image.py "A photo of an astronaut riding a horse on Mars."  1  1
(foo) david@Davids-Mac-mini stable_diffusion % /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/multiprocessing/resource_tracker.py:216: UserWarning: resource_tracker: There appear to be 1 leaked semaphore objects to clean up at shutdown
  warnings.warn('resource_tracker: There appear to be %d '

python --version 3.9.6. OS: Ventura 13.6.1. tried Python 3.11.5 and does same
It cuts off at "There appears to be %d '
Briefly tried installing via source & also tried on conda, and Python 3.12, also didn't work

Add --cfg 0 unfortunately makes no difference
Even if it's running out of memory, why wouldn't it just use the system pagefile/swap for such a small amount like ~134MB? In 20+ years of dev I've never seen malloc() fail from high memory load, it normally just allocs and uses swap ... these 8GB Macs regularly swap like crazy but continue, I often use much MUCH more on these Macs than this appears to be using from Activity Monitor
Or does this have something to do with the unified memory architecture? Or memory fragmentation?
It seems to have no problem running through the default 50 steps - it just fails at the end. I'm watching memory load as this runs and it's in the green most the way, using max 2GB of swap until it completes the 50 steps ... using only 2GB swap it doesn't seem to me like such an excessive memory load that a malloc of just 134MB should fail:
(foo) (base) david@Davids-Mac-mini stable_diffusion % python3 txt2image.py "A cat on a sandwich" --cfg 0 --n_images 1 --n_rows 1
/Users/david/mlx/foo/lib/python3.9/site-packages/urllib3/__init__.py:34: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
  warnings.warn(
100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 50/50 [02:37<00:00,  3.14s/it]
  0%|                                                                                | 0/1 [00:00<?, ?it/s]libc++abi: terminating due to uncaught exception of type std::runtime_error: [malloc_or_wait] Unable to allocate 134217728 bytes.
zsh: abort      python3 txt2image.py "A cat on a sandwich" --cfg 0 --n_images 1 --n_rows 1

(foo) (base) david@Davids-Mac-mini stable_diffusion % python3 txtimage.py "A cat on a sandwich" --cfg 0 --n_images 1 --n_rows 1
/Users/david/mlx/foo/lib/python3.9/site-packages/urllib3/init.py:34: NotOpenSSLWarning: urllib3 v2 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'LibreSSL 2.8.3'. See: https://github.com/urllib3/urllib3/issues/3020
warnings.warn(
100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 50/50 [02:37<00:00,  3.14s/it]
0%|                                                                                | 0/1 [00:00<?, ?it/s]libc++abi: terminating due to uncaught exception of type std::runtime_error: [malloc_or_wait] Unable to allocate 134217728 bytes.
zsh: abort      python3 txt2image.py "A cat on a sandwich" --cfg 0 --n_images 1 --n_rows 1
(foo) (base) david@Davids-Mac-mini stable_diffusion %  /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/multiprocessing/resource_tracker.py:216

I did some more tests, ran it again with --steps 2 - the maximum memory load system hits is about 7.5GB and the entire system is using ONLY ~500MB swap this time. I really don't see why a malloc of just ~134MB should fail under those conditions, why it shouldn't just use swap

New information: I forked mlx itself, changed one line of code, rebuilt from my source fork, and now it works 😊
This line of code in mlx/backend/metal I changed to a much higher limit - this 1.5 seems a bit conservative:
block_limit_(1.5 * device_->recommendedMaxWorkingSetSize()) {}'
There is indeed a relatively big spike of memory usage as it finishes the steps, but not world-ending, I'd rather have 'something that works' even if it spikes my swap, but I suppose it's debatable how best to handle that in the long run as a general solution for all users.

May I say, awesome work :-)
We need to start adding more 8GB Macs in our testing pool. There really wasn't a particular reason for the 1.5. It just gets significantly slower at that point and we wanted to avoid freezing the system.
I would encourage you to at least open an issue or maybe a PR at the main repo. Can't tell you that it will be the first one merged but for sure we 'll test the implications of increasing this limit and if there are none for most use cases then merge it.
Thanks for investigating! Feel free to close the issue and link to it from the PR.

Thank you!
I opened an issue for this on mlx: https://github.com/ml-explore/mlx/issues/63 and created this Pull Request: https://github.com/ml-explore/mlx/pull/64 - hope it's accepted, though of course it's up to the mlx maintainers.


Website down?

Getting a 404 from Github when trying to access https://dephpend.com.
According to https://www.githubstatus.com, Github pages should be up.
Thanks for the tool btw.

I think there is no content for the website.

Or there is a setup error.
It is very strange that files for github-pages are mixed with PHP code...

Resolved the DNS issues with my hoster. Finally back running. Still using gh-pages branch for now which I still have to get rid of at some point, but for now I'm happy it's up and running again.


Rename repo

Since we're now in a dedicated cloud-gov org, we should rename this to product

done


[Bug] Example data on /api/v3/scheduled-search-create/ incorrect

The Months on the example data on https://developer.sailpoint.com/idn/api/v3/scheduled-search-create/ is not correct. It has days instead of months.
"schedule": {
    "type": "WEEKLY",
    "months": {
      "type": "LIST",
      "values": [
        "MON",
        "WED"
      ],

@jason545454 thank you for reporting this.  The scheduled search spec had some other inconsistencies, in addition to incorrect examples, that we fixed.  Please see the new spec that provides additional examples for each schedule type. https://developer.sailpoint.com/idn/api/v3/scheduled-search-create


Failed to add dependencies

Error:(28, 13) Failed to resolve: agency.tango.android:material-intro-screen:{latest_release}
I added the build.grade(Module: app) dependencies yet get the error.

https://github.com/TangoAgency/material-intro-screen/issues/94
https://github.com/TangoAgency/material-intro-screen/issues/37


Howto exit help?

I must be dumb but I cannot find how to quit the help.
I often mistype ctrl+h instead of ctrl+s and I end up in the help. But then I cannot find how to quit it without quitting suplemon completely (eg ctrl+q). I don't see any shortcut in the bottom bar to quit it:

Some keys I thought that could have worked:

ctrl+q. Wrong: it quits suplemon completely.
Escape: no effect.
ctrl+h: could toggle the help... but actually it does not.
ctrl+w (close current tab): but it seems help is not a tab so nothing happened.

I saw #190 but since it was already closed I thought it would be better to create a new issue for that.
Thanks!

Same!

ctrl+w is the correct shortcut for closing help and other tabs. It works fine for me, if it does nothing then the terminal or something else is probably overriding the shortcut. That said making ctrl+h toggle help could be neat.

Thanks to @caph


Unskip required

@knifewine can you review? These are passing now in the skipped-with-require CassCI job, and the relevant JIRAs were closed.
I also removed the re-import of debug in batch_test.py. The debug defined in tools.py is the one that's imported from dtest, so they actually point to the same function. Thus, this change won't change the behavior of debug in the module.

+1 lgtm

Cheers! merging.


Bug fix: Mobile nav collapse

It seems I didn't check the mobile nav properly in my last PR. 😬
When a nav item is clicked in the mobile nav, it should collapse the Navbar, bring it back to its closed position.
But react-bootstrap being made for SPA, collapseOnSelect attribute on the Navbar does not work well with react-router.
The discussions in the react-boostrap recommends installing the react-router-boostrap package, which requires wrapping all the router links(including the Nav links) with a new <LinkContainer> bootstrap element for all router links to work perfectly.
This PR fixes that with a workaround as I don't think currently there is a need to use <LinkContainer> for all the router links as everything else seems to be working fine.
But if you think its better to use that package instead, I will update this PR with the necessary changes.

I just tried this on main and see what you mean.  Thanks for the fix, I think this seems like the best compromise!

Yes, absolutely! I would like to be added to the list of contributors to whichever contribution type(s) you see fit. Thank you.


Wildcard in target paths?

If I am not mistaken, presently TUF specifies that target paths are either files or directories, and previously TUF specified that target paths could contain the wildcard (*) character to denote a positive number of alphanumeric characters (without resorting to the full power of regular expressions in order to control security).
My question is: are we planning to allow wildcards in targets paths? This would make some delegation target paths more compact (e.g. packages/*/D/Django/*).
Thanks!

We would find this useful for the Haskell implementation for Hackage to implement certain existing policies compactly.
We have this cross-cutting "hackage trustee" user role. These users are allowed to edit certain files across all packages in the reporitory (".cabal" package metadata files, but not package ".tar.gz" files), whereas package authors can edit all the files but only for a specific package. To express this trustee policy we would want to have a path like "packages///*.cabal" (corresponding to package/$name/$version/$name.cabal).

Using wildcards in file paths is now supported.  See https://github.com/theupdateframework/tuf/commit/81a147614bb6e07f0d8e2fda1cbd2c8833821d4b


The ^5.1.0+4 version is not building in Android

Environment

Technology
Version

Flutter version
2.0.1

Plugin version
^5.1.0+4

Android version
Android SDK version 29.0.3

Description
Expected behavior: The app should build.
Current behavior: The app is not building and it's showing an error.
Stacktrace/Logcat
Launching lib/main.dart on Android SDK built for x86 in debug mode...
Running Gradle task 'assembleDebug'...
FAILURE: Build failed with an exception.

What went wrong:
Execution failed for task ':app:processDebugResources'.

A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
Android resource linking failed
/home/user/development/example_app/build/flutter_inappwebview/intermediates/library_manifest/debug/AndroidManifest.xml:7:5-11:15: AAPT: error: unexpected element  found in .

Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

Get more help at https://help.gradle.org

BUILD FAILED in 11s
The build failed likely due to AndroidX incompatibilities in a plugin. The tool is about to try using Jetifier to solve the incompatibility.
✏  Creating android/settings_aar.gradle...
✓ android/settings_aar.gradle created successfully.
Building plugin flutter_inappwebview...
Running Gradle task 'assembleAarRelease'...
FAILURE: Build failed with an exception.

Where:
Build file '/home/user/development/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-5.1.0+4/android/build.gradle' line: 22

What went wrong:
A problem occurred evaluating root project 'flutter_inappwebview'.

Failed to apply plugin [id 'com.android.internal.version-check']
Minimum supported Gradle version is 5.6.4. Current version is 5.6.2. If using the gradle wrapper, try editing the distributionUrl in /home/arturo/development/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-5.1.0+4/android/gradle/wrapper/gradle-wrapper.properties to gradle-5.6.4-all.zip

Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

Get more help at https://help.gradle.org

BUILD FAILED in 362ms
Exception: The plugin flutter_inappwebview could not be built due to the issue above.

I solved it changing these files:
android/build.gradle
classpath 'com.android.tools.build:gradle:4.1.0'
android/gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
Hope it helps for those who have the same problem.


Revert "Remove the Pusher panel and code (closes #864)"

Reverts rubykube/peatio#922

Hi @anbuhckr
Thank you for the PR.
We are looking to fully remove UI from Peatio soon. The current UI is used only for QA and should not be affected too much by development. We are removing feature step by step from it.
Sorry, we can't accept the PR.


migrate odo docs from openshift/docs repo to ./docs

Copy OpenShift documentation from https://github.com/openshift/openshift-docs/tree/master/cli_reference/openshift_developer_cli to https://github.com/openshift/odo/tree/master/docs

clean it up so it can be used to generate documentation that we can place to odo.dev site (#2897)

create a script that will sync documentation from our repo to  https://github.com/openshift/openshift-docs/tree/master/cli_reference/openshift_developer_cli. This script ideally open PR on openshift/openshift-docs repo with changes

/remove-triage needs-information

@kadel
I have included instructions on how to "sync" between the openshift repository as well as our current documentation here: https://github.com/openshift/odo/tree/gh-pages
Do you think this is sufficient enough for our documentation?

@kadel
I have included instructions on how to "sync" between the openshift repository as well as our current documentation here: https://github.com/openshift/odo/tree/gh-pages
Do you think this is sufficient enough for our documentation?

+1
Great!
@cdrage can you please share the information on how to update the website and docs with everyone  on<EMAIL_ADDRESS>?

@kadel
Done! As all tasks have been completed. I'm going to close this issue :)


HTML Comment nodes are retrieved as part the .Text() method

CsQuery Version: 1.3.4
.Net Framework: 4.5
Test case (VB):
Dim div As CsQuery.CQ = New CsQuery.CQ("
This is not a comment, nor is this a comment.
")
Dim html As String = div.Html()
Dim text As String = div.Text()

html returns:
"This is not a comment, nor is this a comment."

text returns:
"This is not a comment , but this is a comment , nor is this a comment."

jQuery, by way of comparison, returns the text content without the comment content:
console.log($('
This is not a comment, nor is this a comment.
').text());
"This is not a comment, nor is this a comment."

My workaround was to instantiate the CsQuery.CQ object using the CsQuery.HtmlParsingOptions.IgnoreComments parsing option.
Thank you for this much needed library.

This issue is still present.
Should this be fixed?

My inclination would be to fix it as the purpose of this library seems to be to replicate the functionality of jQuery and this method ha a different behavior in jQuery.

Comments are still being read by Text(). Sometimes an element will contain ie if statements that will incorrectly become the read text:


fix: missing get_lobby_id getter in steam multiplayer peer

Nothing special, just a one-liner with the missing "get_lobby_id" getter which one needs to call void Steam::activateGameOverlayInviteDialog(uint64_t steam_id) .
Fixes #466

Not sure how no one noticed this before but thank you for fixing it!


The CPU is slow

After working on an AES accelerator to be integrated in the user_project_wrapper in caravel, we noticed that the CPU takes around 9000 clock cycles to do a single read or write of a 32-bit register in the user_project_wrapper. The project can be found here: https://github.com/mo-hosni/caravel_aes_example/tree/main
Such simple C code here:
https://github.com/mo-hosni/caravel_aes_example/blob/main/verilog/dv/cocotb/encipher_test/encipher_test.c
takes fractions of a second on 40MHz clock (real time not simulation).
I think there is something wrong here. Or is that normal?

What part of it is slow?  Where are the routines like read_user_double_word and write_user_double_word defined?
The wishbone interface is blocking, so if a process does not return an acknowledge, it can hold the processor indefinitely until it does.  I assume the write_user_ and read_user_ routines are driving the wishbone bus to the user project, so you need to figure out when the user project is returning an acknowledge signal for the write or read, and whether it is spending the time in between doing expected computation.

I debugged this example with @mo-hosni. We found out the wishbone interface isn't blocking the simulation the ack for any user write or read is asserted after 1 cycle. We found out that fetching the instructions is the biggest blocker. Reading the instruction is done via SPI interface. Since the spi flash is 4x slower than the core clock we estimated best case for reading 1 instruction is 32(bits) * 4 (core clocks ) = 128 core clock cycles ignoring times of sending commands and address and any delay between clocks. Also the CPU doesn't have a big cache so it reads some of the instructions more than once. From simulation, I can see the CPU is blocked while fetching the instruction.
I added new test called encipher_test_faster which is exactly the same as the encipher_test  but the test increases the flash_clk to be only 2x slower than core clock by changing the clk_div  value.

Test name
SIM TIME (ns)

encipher_test
10393850.00

encipher_test_faster
5400650.00

The simulation time was approximately halved, as indicated in the table. That's why we think fetching instructions into the CPU using SPI is the biggest contributor to the big simulation needed.
CC: @shalan

@mo-hosni In my own use of Caravel on Arty A7, there is an issue with the LiteX VexRiscV CPU iBus & dBus wishbone arbitrator.  In that the iBus (when fetching from a slow resource, that is SPI flash) will starve the dBus write-back, because the CPU will always trying to feed itself.
While I agree the comment above from @M0stafaRady and the number of cycles is inline with my findings as well.
I think the problem @mo-hosni is experiencing is due to the LiteX component not committing a single write-transaction in a timely manner to their user_project_wrapper hardware device.
One resolution is to force a CPU STALL after an important write-back that needs to be committed over WishBone ASAP, this can be done with minimal side-effects with the instruction lw zero,(zero).  The stall forces the CPU to stop demanding to be fed via iBus which is the only way for the arbitrator to re-assess the grant status and switch it to allow the dBus write-back to proceed (followed by the extra lw zero,(zero)) before it starts demanding instructions from iBus again.  This is entirely normal and expected Vex behaviour but the LiteX adapter provided in Caravel doesn't accommodate in the embedded environment.
When the iBus is being fed by faster memory, such as single-cycle DFF/UserManagedCacheArea, the CPU is slower than the instruction memory this causes there to be natural breaks in iBus demand during such things as reg-write-back so you will not observe the problem as much.  So copying and executing your code to DFF memory 0x0 area is another method to alleviate this.
Even with QSPI the Flash XIP will not reliability keep up with the CPU, the pipeline would remain mostly empty, taking more cycles to fetch 32bit over QSPI clocked at core_clock/2 or worse.
Ideally with Flash XIP and the VexRiscV CPU you want to use the independence of the iBus from the dBus feature so the data path from SPI/XIP controller is separate from the WishBone when the iBus address is in the expected Flash image range.  An independent and parallel data path.
// A verilog surgery fix might look like this (working for me in FPGA,
//  it is totally untested in any other environment and
//  a better solution is to fix the LiteX module directly and rebuild Caravel):
diff --git a/verilog/rtl/mgmt_core.v b/verilog/rtl/mgmt_core.v
index 4a51f5a..b09a476 100644
--- a/verilog/rtl/mgmt_core.v
+++ b/verilog/rtl/mgmt_core.v
@@ -2392,7 +2414,14 @@ always @(*) begin
        endcase
 end
 assign mgmtsoc_litespimmap_spi_dummy_bits = mgmtsoc_litespimmap_storage;
+// | (mgmtsoc_dbus_dbus_cyc & mgmtsoc_dbus_dbus_we & litespi_grant == 1'd0)
+//    litespi_grant == 1'd0 // trying to only activate if this is MMAP mode
+// This will yield the iBus demand on SPI, if there is an outstanding write request issued on dBus
+//  mgmtsoc_dbus_dbus_stb is tied to cyc, maybe done_and_yield works as well as done_or_yield
+wire mgmtsoc_litespimmap_ibus_yield_grant;
+assign mgmtsoc_litespimmap_ibus_yield_grant = (mgmtsoc_dbus_dbus_cyc & mgmtsoc_dbus_dbus_we & litespi_grant == 1'd0);
 assign mgmtsoc_litespimmap_done = (mgmtsoc_litespimmap_count == 1'd0);
+wire mgmtsoc_litespimmap_done_or_yield;
+assign mgmtsoc_litespimmap_done_or_yield = mgmtsoc_litespimmap_done | mgmtsoc_litespimmap_ibus_yield_grant;
 always @(*) begin
        litespi_next_state = 4'd0;
        litespi_next_state = litespi_state;
@@ -2525,7 +2554,7 @@ always @(*) begin
                4'd8: begin
                end
                default: begin
-                       mgmtsoc_litespimmap_burst_cs_litespi_next_value0 = (mgmtsoc_litespimmap_burst_cs & (~mgmtsoc_litespimmap_done));
+                       mgmtsoc_litespimmap_burst_cs_litespi_next_value0 = (mgmtsoc_litespimmap_burst_cs & (~mgmtsoc_litespimmap_done_or_yield));
                end
        endcase
 end
@@ -7135,7 +7244,7 @@ always @(posedge sys_clk) begin
        state <= next_state;
        case (grant)
                1'd0: begin
-                       if ((~request[0])) begin
+                       if ((~request[0] | mgmtsoc_litespimmap_ibus_yield_grant)) begin
                                if (request[1]) begin
                                        grant <= 1'd1;
                                end else begin

// Workaround for such sequences:
//   my_device_register = 0x1234cdef;
//   CPU__STALL_WORKAROUND();
//   for(volatile int i = 0; i < 10000; i++) { ASM_NOP_DELAY(); }
//  /* do something else */

#define CPU_STALL_WORKAROUND()                       \
    /* CPU_STALL_WORKAROUND():                       \
     * Used to induce Caravel Vex RiscV CPU stall to \
     *  enforce dBus write-back in a timely manner.  \
     */                                              \
    __asm__ __volatile__ ("lw zero,(zero)"           \
                  : /* none */                       \
                  : /* none */                       \
                  : /* clobbers: none */ )

FYI - The author of VexRISCV, @Dolu1990, might be interested in this thread.

Does somebody has a simulation wave of the slow behaviour ?

@Dolu1990 This vexrisc_run.tar.gz has wave as well as some logs and files that might me helpful.
To extract: tar -xzvf vexrisc_run.tar.gz

@M0stafaRady Thanks :)
So, looking at it i see nothing wrong, just that the CPU is waiting nearly all the time on the i$ to refill, as the external SPI flash is slow, but in the range of those 128 cycles per 32 bits word.
Not sure if the issue is captured in that wave ?

soc.gtkw.txt

What is the instruction cache configuration ? (bytes / ways)

From my testing (on Arty A7) there does not appear to be a cache, only a CPU working buffer at the frontend of the instruction decoder.
If you execute a branch/jump backwards of just 2 instructions (targeting a 128bit aligned address), the iBus will demand the PC be reloaded (via Flash XIP) for exactly the same data it already just retired even when the next instruction (branch target) address does not cross the current aligned block.  It is difficult to be able to call this a cache as there is no observable cache effect.  It behaves like the Instruction Decoder input working buffer from my observations.
The CPU will speculatively load the next instruction (PC+4), even in a scenario where a branch will occur, the pipeline is empty (because CPU is faster than SPI Flash), while the branch instruction is running (branch insn has to work through that pipeline), the iBus will speculatively ask for PC+4 in the background.  The Flash XIP will service this slower than the retirement of that branch instruction.  Once speculative insn is provided (and discarded) the iBus asks for the target of the branch instruction, which will cause Flash XIP to reset SPI CS (Chip Select) to issue a new READ command from a new address, all adding to the total time to execute the next insn.
There is 1.5 KiB of DFF RAM at memory 0x0 and this operates as single-cycle memory, which might be better called UserManagedCacheSpace.  This is able to feed the CPU iBus to allow the internal CPU pipeline to take effect, the CPU is now slower than the single-cycle memory.
IDD with @RTimothyEdwards comments, a pipelined CPU is great when you can feed that pipeline, even QSPI Flash at core_clock speeds would not be able to feed the (5 stage) Vex.  So I understand the point being made on the choice of using area up to provide that many pipeline stages that you can not feed from the architecture around it.
As stated the Vex is performing as expected, my previous comment concerns the LiteX provided mgmt_core.v and an expectation in the embedded environment for CPU write-back (especially to MMIO hardware) to be performed in a timely manner, even if the program enters a NOP style delay loop immediately after performing that memory-write, which is common with low MHz embedded systems.
The matter is compounded over the lack of WFI support built into the choice of configuration for the CPU (see Issue#36), these things taken together with slow Flash means the iBus can never be idle, except at a CPU STALL condition, once the iBus has the grant of the WishBone it will not release it until the iBus can be made idle.  The LiteX arbitrator (specifically designed for the Vex) just needs to manage things knowing that to achieve a better outcome.

I don't think there is any disagreement in any comment on this issue with @M0stafaRady over the speed and timings found.
What the issue is about is the quoted 9000 cycles to perform a single write (CPU store) to memory (to a MMIO register in the user_project area).  I can explain the conditions on how that might occur and a workaround, in firmware (if working with original verilog), or in verilog (which removes the need to workaround in firmware).
I can not explain how a single read (CPU load) from memory also experiences a 9000 cycle latency, I would be interested also in seeing the waveform demonstrating that.
The 9000 cycle figure is arbitrary, it is possible to write to an internal register, then enter a NOP style delay loop that lasts 10 seconds, then perform a CPU load or store, and finally the write to internal register made 10 seconds ago is committed over WishBone, immediately followed by the recently requested CPU load or store (because the dBus has the grant, it gets to exhaust all the dBus requests before releasing grant), the grant in question is indicated in the 3rd hunk of the diff in my previous comment, mgmt_core.v:7136 verilog net called grant).

@dlmiles / @RTimothyEdwards - Be careful here, VexRISCV is an extremely configurable CPU (https://github.com/SpinalHDL/VexRISCV#description) with a huge number of options which can be selected. It offers 2 stage to 5+ stage variants.
LiteX offers 19 variants as standard (https://github.com/enjoy-digital/litex/blob/9854c9f3228b8c3ff0dd8a66c1afc1f3f3c536a2/litex/soc/cores/cpu/vexriscv/core.py#L31-L49) and the ability to provide a custom variant (which is used by the CFU Playground and Fomu).
Do you know the configuration that was selected for usage in caravel?

BTW There was also a whole bunch of work to create a very fast, very low resource, XIP SPI module for LiteX inside https://github.com/litex-hub/litespi

@dlmiles I blieve this is the wave @mo-hosni was referring to.
I uploaded it to google drive as its size exceeds github limit.
https://drive.google.com/file/d/1yO5sBN5kjPEXANofh3gG9NtF7DK6hih_/view?usp=sharing

@mithro Throwing links and saying look over there doesn't seem particularly relevant to the points raised (I am certainly aware of the links you have provided).  Those links do not change the observable issue by the reporter (or my own findings) with the specific implementation provided inside this github repository.  That is why the issue is logged here.  That is the point of the issue to collaborate and achieve greater understanding of matters.
I don't think anyone is claiming any efficiency concerns with litespi XIP SPI (performance seems good to me here).  I'm not entirely sure where that comment is coming from as the discussion here simply characterises what has been observed with the specific version inside mgmt_core.v provided in this repo.

Just to clarify versions as that is a salient point to raise.
The last comment from me is over the characteristics of the specific Vex version in this repo:  https://github.com/efabless/caravel_mgmt_soc_litex/blob/main/verilog/rtl/VexRiscv_MinDebug.v  last modified in this repo on https://github.com/efabless/caravel_mgmt_soc_litex/commit/6995a07f296332029a93c660b1ea62c763a54995  (2 years ago, Nov 2021)
It is good to be able to characterise the behaviour of the specific version provided in this repository (provided as a good specimen to use) so that others have an informed understanding of it.
I am going to retest the same method with the https://github.com/efabless/caravel_mgmt_soc_litex/blob/main/verilog/rtl/VexRiscv_MinDebugCache.v (which does have ICache at https://github.com/efabless/caravel_mgmt_soc_litex/blob/main/verilog/rtl/VexRiscv_MinDebugCache.v#L4413 )
this was last modified in this repo Sep 2022 https://github.com/efabless/caravel_mgmt_soc_litex/commit/f44fbcd3f2e10a5a1b03e3a23d33eb955bf2d434
The https://github.com/efabless/caravel_mgmt_soc_litex/blob/main/verilog/rtl/mgmt_core.v last modified https://github.com/efabless/caravel_mgmt_soc_litex/commit/1321c51aeedc19405f5a20b68edc5bdc4fab5c57 (10 months ago, Oct 2022).
These would be the versions in the main branch at this time of this project, I did not find a more recently maintained branch.

@M0stafaRady Thanks for the VCD after quick look at it:
Do you have a time index I should be looking at.  What is the hardware device address being accessed that takes 9000 cycles ?
There are 2 main areas where dBus latency is higher than at other times (seen as dBus_CYC becoming active), under the red vertical highlight bar and towards the right of image shown soon after GPIO 1-bit is on (top signal). The image only has around 2/3 of the total VCD but there are no events as congested at a later timeline.
Picking out the example under the red vertical highlight bar, latency for a dBus read looks to be approx ~1479 core_clock cycles (clk) an example is at 1537175ns and the delay is for 36975ns (clk 25ns period).   PC=0x10002cfc and it looks to be stack push/pop not an access to a user_project MMIO device register.
This looks to be due to blocking iBus load (8 x 32bit), the 1479 core_clock cycles is in the order of ~11.5 x 32bit words of time to communicate over SPI.  8 being the instructions, 2 x 32bit words of time being due to SPI command/address (the sequence occurs twice in the timeframe) and turnaround time.
Here is the zoomed out view of the area I picked out fro your gcloud download files (I would expect 9000 cycles blocking latency to be visible at this zoom factor).

@dlmiles -  Apologize for the noise -- I was skimming the issue and wrongly concluded that "CPU is slow" was referring to "VexRISCV executing from XSPI" (there has been a lot of iteration in the LiteX community around that topic).

@mo-hosni Do you remember the time index for the longest writing ?

@M0stafaRady Thanks for the VCD after quick look at it:
Do you have a time index I should be looking at. What is the hardware device address being accessed that takes 9000 cycles ?
There are 2 main areas where dBus latency is higher than at other times (seen as dBus_CYC becoming active), under the red vertical highlight bar and towards the right of image shown soon after GPIO 1-bit is on (top signal). The image only has around 2/3 of the total VCD but there are no events as congested at a later timeline.
Picking out the example under the red vertical highlight bar, latency for a dBus read looks to be approx ~1479 core_clock cycles (clk) an example is at 1537175ns and the delay is for 36975ns (clk 25ns period). PC=0x10002cfc and it looks to be stack push/pop not an access to a user_project MMIO device register.
This looks to be due to blocking iBus load (8 x 32bit), the 1479 core_clock cycles is in the order of ~11.5 x 32bit words of time to communicate over SPI. 8 being the instructions, 2 x 32bit words of time being due to SPI command/address (the sequence occurs twice in the timeframe) and turnaround time.
Here is the zoomed out view of the area I picked out fro your gcloud download files (I would expect 9000 cycles blocking latency to be visible at this zoom factor).

@M0stafaRady, @dlmiles  : I just looked at the waveforms again,
For example writing data as in this for loop here:
https://github.com/efabless/caravel_aes_example/blob/a1331908121e225b8cd6064d06b0bb2f7e87401a/verilog/dv/cocotb/encipher_test/encipher_test.c#L27
The CPU takes 8120 clock cycle between each write to fill the register uut/chip_core/mprj/mprj/aes/core_key.

Hi @mo-hosni
Where is defined USER_writeWord ? Can you send your compiled elf file ?

@Dolu1990
User_writeWord defined here
elf file: decipher_o.zip

So, looking at the assembly, i can see :
100026d0 <USER_writeWord>:
100026d0:	fe010113          	addi	sp,sp,-32
100026d4:	00812e23          	sw	s0,28(sp)
100026d8:	02010413          	addi	s0,sp,32
100026dc:	fea42623          	sw	a0,-20(s0)
100026e0:	feb42423          	sw	a1,-24(s0)
100026e4:	fe842783          	lw	a5,-24(s0)
100026e8:	00279713          	slli	a4,a5,0x2
100026ec:	300007b7          	lui	a5,0x30000
100026f0:	00f707b3          	add	a5,a4,a5
100026f4:	fec42703          	lw	a4,-20(s0)
100026f8:	00e7a023          	sw	a4,0(a5) # 30000000 <_erodata+0x1fffcee0>
100026fc:	00000013          	nop
10002700:	01c12403          	lw	s0,28(sp)
10002704:	02010113          	addi	sp,sp,32
10002708:	00008067          	ret

which use 3 block of instruction cache, on that you also have to add the cache blocks used by the loop, not sure how many it is, likely 1 or 2. (1 block is 32 byte, aligned)
So, let's assume it's overal 5 blocks => 1200*5 cycles for each iteration (as the instruction cache seems to only have 2 blocks, it overflow), meaning 6000 cycles would be waiting on SPI flash.
I would say, what could be done is just to inline the USER_writeWord function, this should realy speed up things.
Also, forcing functions to be 32 bytes aligned may help.

So it is the distance (in cycles) between two writes being presented to the hardware over WishBone the 9000 cycle measurement is from.  These writes are using an iteration loop https://github.com/efabless/caravel_aes_example/blob/main/verilog/dv/cocotb/encipher_test/encipher_test.c and a function USER_writeWord() with stack saving to perform a single SW (StoreWord) instruction (which is the purpose of the function) to the hardware device at the WishBone user_project address.
From the comment in other threads it has been identified loading instructions costs between 128 and 144 cycles per instruction, even if the CPU can execute and retire that instruction in just a few cycles.  It looks like a lot of instructions are used to achieve a goal.
The USER_writeWord function is convenient but....
The fragment of assembler indicates the version you are using is built with compiler options that would:

keep the stack-frame (maybe to assist debugging) when it is possible to remove it (maybe -fomit-frame-pointer can do this)
a large stack frame at that (using 32byte granularity when it is RV32, target platform has embedded RAM limitations and 16 bytes is the ABI requirement)
inserts NOP (presumably for a scheduling benefit of some other RiscV CPU arch that is not the Vex)
There are obviously some improvement to be made there to reduce both instruction count to implement the method as-is and the excessive use of load/store to achieve the same goal as:

# with the above taken into account may it is possible to have the compiler emit an implementation that looks more like:
.global USER_writeWord
USER_writeWord:
  slli	  a1,a1,0x2   # * sizeof(u_int32_t)
  lui     a2,0x30000  # USER_PROJECT_WISHBONE_ADDRESS_BASE = 0x30000000
  add     a1,a1,a2
  sw      a0, 0(a1)
  ret

This would lend itself to inlining as all the writes to hardware can use a common base within RiscV 12-bit offset stores
A version in C that removes the need to use the convenient USER_writeWord() function:
volatile u_int32_t *hardware_base = (u_int32_t) 0x30000000;

const u_int32_t *data = (const u_int32_t *) key;  // as per the single_block_encipher() argument
volatile u_int32_t *hardware_reg_key = (u_int32_t) (hardware_base + (/*offset*/ 0x10 * sizeof(u_int32_t)));
for(int i = 0; i < 8; i++)
  hardware_reg_key[i] = data[i];  // USER_writeWord(data[i], 0x10 + i)

Another option on this platform is to copy the program into the 1536 bytes of DFF RAM at address 0x0.
There is a setup cost of doing the copy (during startup), as you'd need to read from flash all the .text data to copy it before execution can begin.  So this will not speed up the main() total execution time.  But if you split init() and run_test() you could speed up the run_test() part for example if you wanted to performance measure your custom hardware.
Once execution starts (from address 0x000 to 0x600 it should occur at cached speeds).  With optimization such as the example USER_writeWord rewrite as above it shoud fit in that space with plenty of room to spare.

Another option maybe you can improve the SPI clock divider ?  I think it is core_clock/4 by default, so 10MHz if you are running at 40MHz but maybe /2 or /1 is possible.


无法上传，报错为AccessToken is invalid. AccessTokenExpired

命令：aliyunpan upload /root/rec_data/ /backup --ow --norapid --retry 5 --bs 51200
版本：0.2.6
报错：
[2023-2-18 20:24:09.620] begin to upload part: 90
[2023-2-18 20:24:09.620] do request url: https://api.aliyundrive.com/v2/file/get_upload_url
[2023-2-18 20:24:09.668] AccessToken is invalid. AccessTokenExpired
[2023-2-18 20:24:09.668] multiUpload worker upload file done
[2023-2-18 20:24:09.668] upload file part err: %+v UrlExpired
[2023-2-18 20:24:09.668] upload err: %s, id: %d
 UrlExpired 90
[2023-2-18 20:24:09.668] begin to upload part: 90
[2023-2-18 20:24:09.668] do request url: https://api.aliyundrive.com/v2/file/get_upload_url
[2023-2-18 20:24:09.720] AccessToken is invalid. AccessTokenExpired
[2023-2-18 20:24:09.720] multiUpload worker upload file done
[2023-2-18 20:24:09.720] upload file part err: %+v UrlExpired
[2023-2-18 20:24:09.720] upload err: %s, id: %d
 UrlExpired 90
[2023-2-18 20:24:09.720] begin to upload part: 90
[2023-2-18 20:24:09.721] do request url: https://api.aliyundrive.com/v2/file/get_upload_url
[2023-2-18 20:24:09.768] AccessToken is invalid. AccessTokenExpired
[2023-2-18 20:24:09.768] multiUpload worker upload file done
[2023-2-18 20:24:09.768] upload file part err: %+v UrlExpired
[2023-2-18 20:24:09.768] upload err: %s, id: %d
 UrlExpired 90
[2023-2-18 20:24:09.768] begin to upload part: 90
[2023-2-18 20:24:09.768] do request url: https://api.aliyundrive.com/v2/file/get_upload_url
[2023-2-18 20:24:09.846] AccessToken is invalid. AccessTokenExpired
[2023-2-18 20:24:09.846] multiUpload worker upload file done
[2023-2-18 20:24:09.846] upload file part err: %+v UrlExpired
[2023-2-18 20:24:09.846] upload err: %s, id: %d
 UrlExpired 90
[2023-2-18 20:24:09.846] begin to upload part: 90
[2023-2-18 20:24:09.846] do request url: https://api.aliyundrive.com/v2/file/get_upload_url
[2023-2-18 20:24:09.895] AccessToken is invalid. AccessTokenExpired
[2023-2-18 20:24:09.896] multiUpload worker upload file done
[2023-2-18 20:24:09.896] upload file part err: %+v UrlExpired
[2023-2-18 20:24:09.896] upload err: %s, id: %d
 UrlExpired 90
[2023-2-18 20:24:09.896] begin to upload part: 90
[2023-2-18 20:24:09.896] do request url: https://api.aliyundrive.com/v2/file/get_upload_url
[2023-2-18 20:24:09.947] AccessToken is invalid. AccessTokenExpired
[2023-2-18 20:24:09.947] multiUpload worker upload file done
[2023-2-18 20:24:09.947] upload file part err: %+v UrlExpired
[2023-2-18 20:24:09.947] upload err: %s, id: %d
 UrlExpired 90
[2023-2-18 20:24:09.947] begin to upload part: 90
[2023-2-18 20:24:09.947] do request url: https://api.aliyundrive.com/v2/file/get_upload_url
[2023-2-18 20:24:09.994] AccessToken is invalid. AccessTokenExpired
[2023-2-18 20:24:09.994] multiUpload worker upload file done
[2023-2-18 20:24:09.994] upload file part err: %+v UrlExpired
[2023-2-18 20:24:09.994] upload err: %s, id: %d
 UrlExpired 90

上传一段时间后就会一直循环报上述错误无法继续上传
之前一直用的0.2.2版本还可以正常上传，refreshtoken一直在每小时刷新一次

我也有同样的问题，只能每过一个小时重启一下容器

我也有同样的问题，只能每过一个小时重启一下容器

我不是的用docker，类似处理还有什么呀

token会自动刷新的，确认下你的服务器的时区是否OK，是不是东八区

token会自动刷新的，确认下你的服务器的时区是否OK，是不是东八区。 如果日志全，也可以看看没有这种日志
access token expired, get new from refresh token
get new access token success

确认为东八区，debug日志里没查到关于refresh的句子
出错分段的日志如下
[2] ↑ 3.37GB/3.43GB 768.74KB/s(768.74KB/s) in 1h25m52s ............
[2] ↑ 3.37GB/3.43GB 672.05KB/s(672.05KB/s) in 1h25m53s ............
[2] ↑ 3.37GB/3.43GB 384.15KB/s(384.16KB/s) in 1h25m54s ............
[2023-2-22 14:21:14.733] multiUpload worker upload file done
[2023-2-22 14:21:14.733] begin to upload part: 69
[2023-2-22 14:21:14.733] do request url: https://cn-beijing-data.aliyundrive.net/ETEo9HrG%2F1552815%2F63f5a038b41bbae63d394c4fbc12e5a0596c8fd5%2F63f5a0385103fee8e4bb4713969e2bded2c2c0e4?partNumber=70&security-token=CAIS%2

[2] ↑ 3.37GB/3.43GB 736.13KB/s(735.98KB/s) in 1h25m55s ............
[2] ↑ 3.37GB/3.43GB 767.68KB/s(768.00KB/s) in 1h25m56s ............
[2] ↑ 3.37GB/3.43GB 512.12KB/s(640.08KB/s) in 1h25m57s ............
[2] ↑ 3.42GB/3.43GB 572.90KB/s(572.90KB/s) in 1h27m6s ............
[2] ↑ 3.42GB/3.43GB 771.92KB/s(771.92KB/s) in 1h27m7s ............
[2] ↑ 3.42GB/3.43GB 769.79KB/s(769.79KB/s) in 1h27m8s ............
[2023-2-22 14:22:29.389] multiUpload worker upload file done
[2023-2-22 14:22:29.389] begin to upload part: 70
[2023-2-22 14:22:29.389] do request url: https://cn-beijing-data.aliyundrive.net/ETEo9HrG%2F1552815%2F63f5a038b41bbae63d394c4fbc12e5a0596c8fd5%2F63f5a0385103fee8e4bb4713969e2bded2c2c0e4?partNumber=71&security-token=CAIS%

[2] ↑ 3.42GB/3.43GB 511.93KB/s(511.64KB/s) in 1h27m9s ............
[2] ↑ 3.42GB/3.43GB 768.49KB/s(768.91KB/s) in 1h27m10s ............
[2] ↑ 3.42GB/3.43GB 768.06KB/s(768.27KB/s) in 1h27m11s ............
[2] ↑ 3.42GB/3.43GB 512.36KB/s(512.36KB/s) in 1h27m12s ............
[2] ↑ 3.42GB/3.43GB 639.95KB/s(639.95KB/s) in 1h27m13s ............
[2] ↑ 3.42GB/3.43GB 768.36KB/s(768.36KB/s) in 1h27m14s ............
[2] ↑ 3.42GB/3.43GB 672.29KB/s(672.29KB/s) in 1h27m15s ............
[2] ↑ 3.42GB/3.43GB 767.59KB/s(767.59KB/s) in 1h27m16s ............
[2] ↑ 3.42GB/3.43GB 575.91KB/s(575.91KB/s) in 1h27m17s ............
[2] ↑ 3.42GB/3.43GB 768.03KB/s(768.02KB/s) in 1h27m18s ............
[2] ↑ 3.43GB/3.43GB 768.24KB/s(768.24KB/s) in 1h27m19s ............
[2] ↑ 3.43GB/3.43GB 576.04KB/s(576.04KB/s) in 1h27m20s ............
[2] ↑ 3.43GB/3.43GB 592.71KB/s(592.71KB/s) in 1h27m21s ............
[2023-2-22 14:22:42.109] multiUpload worker upload file done
[2023-2-22 14:22:42.109] do request url: https://api.aliyundrive.com/v2/file/complete
[2023-2-22 14:22:42.247] upload file commit failed: AccessToken is invalid. AccessTokenExpired
[2] 2023-02-22 14:22:23 文件上传结果： 失败！上传文件失败,AccessToken is invalid. AccessTokenExpired 耗时 1小时27分27秒
[2] 上传文件失败, AccessToken is invalid. AccessTokenExpired, 重试 1/5
[2] 2023-02-22 14:22:23 准备上传: /root/rec_data/ttt.flv => /backup/ttt.flv
[2023-2-22 14:22:44.247] [2] 2023-02-22 14:22:23 准备结束, 准备耗时 0秒
[2023-2-22 14:22:44.247] upload task CREATED from instance state

[2023-2-22 14:22:44.248] begin to upload part: 70
[2023-2-22 14:22:44.248] do request url: https://cn-beijing-data.aliyundrive.net/ETEo9HrG%2F1552815%2F63f5a038b41bbae63d394c4fbc12e5a0596c8fd5%2F63f5a0385103fee8e4bb4713969e2bded2c2c0e4?partNumber=71&security-token=CAIS%2

[2] ↑ 3.42GB/3.43GB 5.08MB/s(1.24MB/s) in 1s ............
[2] ↑ 3.42GB/3.43GB 3.08MB/s(1.31MB/s) in 2s ............
[2] ↑ 3.42GB/3.43GB 0B/s(669.79KB/s) in 3s ............
[2] ↑ 3.42GB/3.43GB 1.38MB/s(1.38MB/s) in 4s ............
[2] ↑ 3.42GB/3.43GB 706.51KB/s(706.50KB/s) in 5s ............
[2] ↑ 3.43GB/3.43GB 1.34MB/s(1.34MB/s) in 6s ............
[2] ↑ 3.43GB/3.43GB 0B/s(0B/s) in 7s ............
[2] ↑ 3.43GB/3.43GB 0B/s(0B/s) in 8s ............
[2] ↑ 3.43GB/3.43GB 0B/s(0B/s) in 9s ............
[2] ↑ 3.43GB/3.43GB 0B/s(0B/s) in 10s ............
[2] ↑ 3.43GB/3.43GB 0B/s(0B/s) in 11s ............
[2023-2-22 14:22:56.175] 分片上传出错: 分片70 => <?xml version="1.0" encoding="UTF-8"?>
<Error>
  PartAlreadyExist
  <Message>For sequential multipart upload, you can't overwrite uploaded parts.</Message>
  <RequestId>63F5B4B473F4E53034A3FD25</RequestId>
  <HostId>cn-beijing-data.aliyundrive.net</HostId>
  <PartEtag>"EEFCC7F3208DC5C6AD3A7188CAEA74A1"</PartEtag>
  <PartNumber>71</PartNumber>
  <EC>0042-00000108</EC>
</Error>

[2023-2-22 14:22:56.175] upload file data chunk error  PartAlreadyExist
[2023-2-22 14:22:56.175] multiUpload worker upload file done
[2023-2-22 14:22:56.175] do request url: https://api.aliyundrive.com/v2/file/complete
[2023-2-22 14:22:56.232] upload file commit failed: AccessToken is invalid. AccessTokenExpired
[2] 2023-02-22 14:22:23 文件上传结果： 失败！上传文件失败,AccessToken is invalid. AccessTokenExpired 耗时 11秒
[2] 上传文件失败, AccessToken is invalid. AccessTokenExpired, 重试 2/5
[2] 2023-02-22 14:23:23 准备上传: /root/rec_data/ttt.flv => /backup/ttt.flv
[2023-2-22 14:23:00.234] [2] 2023-02-22 14:23:23 准备结束, 准备耗时 0秒
[2023-2-22 14:23:00.234] upload task CREATED from instance state

[2023-2-22 14:23:00.234] begin to upload part: 70
[2023-2-22 14:23:00.234] do request url: https://cn-beijing-data.aliyundrive.net/ETEo9HrG%2F1552815%2F63f5a038b41bbae63d394c4fbc12e5a0596c8fd5%2F63f5a0385103fee8e4bb4713969e2bded2c2c0e4?partNumber=71&security-token=CAIS%2B

[2] ↑ 3.42GB/3.43GB 1.84MB/s(247.30KB/s) in 1s ............
[2] ↑ 3.42GB/3.43GB 1.17MB/s(576.35KB/s) in 2s ............
[2] ↑ 3.42GB/3.43GB 768.06KB/s(672.23KB/s) in 3s ............
[2] ↑ 3.42GB/3.43GB 768.03KB/s(768.01KB/s) in 4s ............
[2] ↑ 3.42GB/3.43GB 575.90KB/s(671.95KB/s) in 5s ............
[2] ↑ 3.42GB/3.43GB 640.30KB/s(640.30KB/s) in 6s ............
[2] ↑ 3.42GB/3.43GB 703.91KB/s(703.91KB/s) in 7s ............
[2] ↑ 3.42GB/3.43GB 767.84KB/s(767.84KB/s) in 8s ............
[2] ↑ 3.42GB/3.43GB 576.45KB/s(576.45KB/s) in 9s ............
[2] ↑ 3.43GB/3.43GB 672.18KB/s(672.18KB/s) in 10s ............
[2] ↑ 3.43GB/3.43GB 576.23KB/s(576.23KB/s) in 11s ............
[2023-2-22 14:23:12.114] 分片上传出错: 分片70 => <?xml version="1.0" encoding="UTF-8"?>
<Error>
  PartAlreadyExist
  <Message>For sequential multipart upload, you can't overwrite uploaded parts.</Message>
  <RequestId>63F5B4C4005C573839FDE0B8</RequestId>
  <HostId>cn-beijing-data.aliyundrive.net</HostId>
  <PartEtag>"EEFCC7F3208DC5C6AD3A7188CAEA74A1"</PartEtag>
  <PartNumber>71</PartNumber>
  <EC>0042-00000108</EC>
</Error>

[2023-2-22 14:23:12.114] upload file data chunk error  PartAlreadyExist
[2023-2-22 14:23:12.114] multiUpload worker upload file done
[2023-2-22 14:23:12.115] do request url: https://api.aliyundrive.com/v2/file/complete
[2023-2-22 14:23:12.164] upload file commit failed: AccessToken is invalid. AccessTokenExpired
[2] 2023-02-22 14:23:23 文件上传结果： 失败！上传文件失败,AccessToken is invalid. AccessTokenExpired 耗时 11秒
[2] 上传文件失败, AccessToken is invalid. AccessTokenExpired, 重试 3/5
[2] 2023-02-22 14:23:23 准备上传: /root/rec_data/ttt.flv => /backup/ttt.flv

有点奇怪，代码中是有token定时刷新的。除非刷新的时候token刷新失败了才会理论出现上面的错误。
你有试过重新用新的refresh token登录去上传，看看结果如何

我发现我的已经自动恢复了，之前我都是通过群晖的定时任务半小时重启一次，昨天还是前天我取消了，至今没啥问题。

有点奇怪，代码中是有token定时刷新的。除非刷新的时候token刷新失败了才会理论出现上面的错误。 你有试过重新用新的refresh token登录去上传，看看结果如何

emmm还是不行，尝试过重新登录，没有改变。这段时间忘关定时任务了，每天都在重复死循环零速上传，日志给循环到50多mb了😂


Revert "Even smaller container!"

Reverts vespa-engine/vespa#6798

You were right, @andreer :(

Merging to fix broken integration tests.

aaw