[core] add MPTCP support

Multipath TCP (MPTCP), standardized in RFC8684 [1], is a TCP extension
that enables a TCP connection to use different paths.
Multipath TCP has been used for several use cases.
On smartphones, Multipath TCP enables seamless handovers between
cellular and Wi-Fi networks while preserving established connections.
This use-case is what pushed Apple to use MPTCP since 2013 in multiple
applications [2]. On dual-stack hosts, Multipath TCP enables the TCP
connection to automatically use the best performing path,
either IPv4 or IPv6. If one path fails, Multipath TCP automatically
uses the other path. To benefit from MPTCP, both the client and the
server have to support it.
Multipath TCP is a backward-compatible TCP extension that is enabled by
default on recent Linux distributions (Debian, Ubuntu, Redhat, ...).
Multipath TCP is included in the Linux kernel since version 5.6 [3].
To use Multipath TCP on Linux, a server application must explicitly
enable it when creating the socket. No need to change anything else in
the application. This is what the attached patch is doing.
It is important to note that a MPTCP-enabled server continues to accept
regular TCP connections that do not use the Multipath TCP extension
without any performance impact.
When a connection request is received, and is linked to a listening
socket with MPTCP support, the kernel will simply check if MPTCP
options are present. If not, the accepted socket will be a "plain" TCP
one.
This commit modifies the creation of sockets on Linux, trying to use
Multipath TCP is available. If not, a plain TCP socket is created
instead. A new option is now available: server.network-mptcp. This
option is enabled by default. It seems important to enable this option
by default on the server side, to let clients using MPTCP while not
degrading performances when "plain" TCP is used. If the option is not
enabled by default, it looks difficult to convince each administrator to
enable it explicitly. This technology is mainly useful for the client
side while it doesn't change much for the server side where no other
configuration is needed.
Link: https://www.rfc-editor.org/rfc/rfc8684.html [1]
Link: https://www.tessares.net/apples-mptcp-story-so-far/ [2]
Link: https://www.mptcp.dev [3]
Co-developed-by: Maxime Dourov<EMAIL_ADDRESS>Co-developed-by: Olivier Bonaventure<EMAIL_ADDRESS>Co-developed-by: Matthieu Baerts<EMAIL_ADDRESS>Signed-off-by: Maxime Dourov (UCLouvain<EMAIL_ADDRESS>

Thank you for suggesting the patch.
If the feature was disabled by default, I would accept the patch as submitted.  However, you are suggesting that this feature be enabled by default.  Your entire justification is "If the option is not enabled by default, it looks difficult to convince each administrator to enable it explicitly" which translates to little more than "I want clients to be able to use this feature, so enable it by default on servers".
First, what are the security and privacy implications, if any, to client or server, of enabling this by default in lighttpd?
What are the potential implications, if any, for enabling this on servers reached via less-than-intelligent proxies?
Second, would you please point me to established documentation to corroborate your statement that enabling MPTCP on listening sockets is "without any performance impact"?  https://www.mptcp.dev/ notes the feature "Fallback from MPTCP to TCP if the peer or a middlebox do not support MPTCP."  There is no performance impact to this?  Fallback is good.  However, lighttpd may be run on very small embedded systems, so extra cost needs to be accurately accounted, even if there is transparent fallback so that things do not break.
Third, if enabling this by default, perhaps this feature should be available only when IPPROTO_MPTCP is defined, and the code block enabling the feature should be wrapped in #ifdef IPPROTO_MPTCP ... #endif, rather than defining the missing define.  Otherwise, log_pdebug() will end up issuing trace for everyone running newer versions of lighttpd on old systems, since log_pdebug() ends up in the error log, which is the default used by many people.  log_pdebug() is filtered by syslog only if people have configured lighttpd logging to use syslog, which is not the default in lighttpd.
Fourth, is multipath TCP available only on Linux?  I think it is more widely available.  Restricting it to Linux is a limitation of this patch.  However, multipath TCP must also be available on macOS and iOS if Apple enables it in clients.  lighttpd can be run on a wide variety of servers, including some which you might consider clients such as phones (e.g. Android or iOS).

To be clear, I would like to support MPTCP and this patch, but I have questions since I am not an expert in MPTCP.  Before enabling this by default in lighttpd, I need to have a stronger understand of potential implications and effects of doing so.  Thank you.

FreeBSD support for multipath TCP: https://freebsdfoundation.org/project/multipath-tcp-for-freebsd/

Regarding the git usage of this PR, please do not merge the master branch.  Instead, git rebase master.  You can git checkout -b mptcp master and then git cherry-pick ab136194 to have a cleaner mptcp feature branch without the merge.  In general, it is good practice to work on feature branches (instead of 'master') when submitting PRs or merge requests to other repositories.

How does MPTCP (at the transport layer) compare with the feature of HTTP/3 QUIC streams (closer to the application layers) which can be transported over multiple paths?

Hi @gstrauss
(I worked on this patch with Maxime)

Thank you for suggesting the patch.

Thank you for your review and the question.

If the feature was disabled by default, I would accept the patch as submitted. However, you are suggesting that this feature be enabled by default. Your entire justification is "If the option is not enabled by default, it looks difficult to convince each administrator to enable it explicitly" which translates to little more than "I want clients to be able to use this feature, so enable it by default on servers".

We understand your reaction. I think adding a bit more context about our work here with Maxime at UCLouvain might help.
UCLouvain is a university in Belgium where a lot of development around Multipath TCP (and Multipath QUIC) has been done. Today, MPTCP is available in the Linux kernel and iOS, but is mainly used by big companies: mainly Apple for some of their apps, some specific use-cases in datacenters, and ISPs to use both the cellular and the fixed network for some clients. In all these cases, the companies behind them control both the clients and the servers. If someone wants to have an app using MPTCP, they often simply use a tool like mptcpize to force the creation of an MPTCP socket, instead of a TCP one, thanks to LD_PRELOAD (or eBPF, or systemtap) as explained in different articles, like here. That's great and easy, but it doesn't help to spread its usage: people will only use it with services they control, and some sysadmins might not like using LD_PRELOAD. It is frustrating to have to tell people to deploy a proxy to benefit from MPTCP, e.g., by using multiple (slow) Internet links to have something decent. So I'm leading a new small project at the UCLouvain with Olivier Bonaventure, to improve the situation. (Note that I'm not affiliated with UCLouvain; I'm just helping here with this project; I'm working on my own on MPTCP in the kernel at the moment.)
With the help of two students who want to learn by doing useful things in open source, we are trying to add native support to different apps. Our "dream" would be to have MPTCP enabled by default on the server side, so people can start using it with multiple servers without a proxy or asking sysadmins to enable it. In our minds, because of its low impact, it should not matter to have it enabled for a sysadmin: it is in theory as secured as TCP (see below), the server will continue to serve files, and this might be done quicker, or without interruptions when the client is switching from one network to another.
But you are right; it is not as simple.

First, what are the security and privacy implications, if any, to client or server, of enabling this by default in lighttpd?

Regarding the security implications of the protocol, it is described in RFC 8684. In summary, the fundamental goal is for the security of MPTCP to be "no worse" than regular TCP today.
Regarding the security implications of the Linux kernel implementations, it is like any software; there might be issues. But the Linux kernel is also known to quickly fix security issues once they have been identified.
For the privacy concerns, the RFC doesn't mention anything, I think, but it looks like it is similar to TCP. Of course, here, if a client is doing a long transfer while switching from one network to another, the server can see it is the same client. Without MPTCP, the server would see the same requests twice, but from two different IPs. MPTCP can be used to improve privacy: if a path is known as being untrusted, but cheap, some data --e.g., TLS handshakes -- could be done over another path, trusted but more expensive.

What are the potential implications, if any, for enabling this on servers reached via less-than-intelligent proxies?

Sorry, I'm not sure if I understand the question. If these proxies initiating connections to our server don't support MPTCP, MPTCP will not be used. Technically, if a request is established without MPTCP options in the TCP header, the Linux kernel will create a "plain" TCP socket, which is used by the userspace after an accept().

Second, would you please point me to established documentation to corroborate your statement that enabling MPTCP on listening sockets is "without any performance impact"?

We need to work on such a document, sorry. Just to be precise, there is no real performance impact if the client doesn't support MPTCP; apart from checking if MPTCP options are present in the TCP header, that's negligible. Here is what the kernel code is saying when the userspace uses accept() when there are no (or bad) MPTCP options in the request:
/* we are being invoked after accepting a non-mp-capable
 * flow: sk is a tcp_sk, not an mptcp one.
 *
 * Hand the socket over to tcp so all further socket ops
 * bypass mptcp.
 */

When MPTCP is used, there is a small impact because there is an extra layer. It is difficult to measure the impact: we can do that when only one path is used, and see that the impact is extremely low, but it is mainly caused by a few bytes (~20B) added in the TCP header for MPTCP to work. When multiple subflows are used, the server will send data at a higher rate, or not have to re-send files.

https://www.mptcp.dev/ notes the feature "Fallback from MPTCP to TCP if the peer or a middlebox do not support MPTCP." There is no performance impact to this?

To be able to survive on the "wild" Internet, MPTCP connections should be able to fall back to TCP in case of issues. Typically, a client initiates an MPTCP connection, and a middlebox will drop MPTCP options from the TCP headers because they are "unknown". On the server side, it will receive a request without MPTCP options; that's fine: a plain TCP socket will be created. If MPTCP options are dropped (or altered) later, the MPTCP socket will continue to be used, but it will directly call the TCP layer. That's the "extra layer" we cannot avoid. But as it is done nicely on the kernel side, the impact is very low.

Fallback is good. However, lighttpd may be run on very small embedded systems, so extra cost needs to be accurately accounted, even if there is transparent fallback so that things do not break.

Good point. I don't have any numbers to share for embedded systems, even if I used to work for a company where we were installing a TCP-2-MPTCP proxy on residential gateways. These routers were less powerful than most Raspberry Pi's :)

Third, if enabling this by default, perhaps this feature should be available only when IPPROTO_MPTCP is defined, and the code block enabling the feature should be wrapped in #ifdef IPPROTO_MPTCP ... #endif, rather than defining the missing define. Otherwise, log_pdebug() will end up issuing trace for everyone running newer versions of lighttpd on old systems, since log_pdebug() ends up in the error log, which is the default used by many people. log_pdebug() is filtered by syslog only if people have configured lighttpd logging to use syslog, which is not the default in lighttpd.

I don't think it is a good idea to restrict this with #ifdef IPPROTO_MPTCP: IPPROTO_MPTCP is defined in the libC, independently of the kernel being used, potentially out-to-date compared to the kernel then. And this is at build time. Same to check at build time if MPTCP is available: that's potentially a different environment than the one used at run time. For example, Debian builds packages for any Debian versions on (old) stable versions servers, where they do a chroot with packages from different Debian versions. The kernel might not be the one used at runtime. (Or MPTCP could be disabled on these kernels used during the build.)
I didn't know about the impact of the log. We thought it would be OK because there will be only one log entry at the start of a server, no?
If this is still too many, should we maybe restrict it only if there was an unexpected errno? Creating a socket with IPPROTO_MPTCP will fail with either ENOPROTOOPT (Protocol not available: linked to net.mptcp.enabled sysctl), EPROTONOSUPPORT (Protocol not supported: MPTCP is not compiled on >= v5.6), or EINVAL (Invalid argument: MPTCP is not available on kernels < 5.6).

Fourth, is multipath TCP available only on Linux? I think it is more widely available. Restricting it to Linux is a limitation of this patch. However, multipath TCP must also be available on macOS and iOS if Apple enables it in clients. lighttpd can be run on a wide variety of servers, including some which you might consider clients such as phones (e.g. Android or iOS).

It is easily accessible with Linux, thanks to IPPROTO_MPTCP.
On iOS, it is available, but well:

It is easy if you use their SDK: doc
If not, you need to use private libraries (I'm not even sure the headers are available) with specific functions to create sockets, e.g., OpenSSH for iOS

On FreeBSD, there was an ongoing implementation, but that was years ago, as you mentioned.
There are other implementations, but on specific systems (Citrix load balancer, userspace, etc.):
So I think it is best to restrict this to Linux only for the moment.

Regarding the git usage of this PR, please do not merge the master branch.

Sorry for that: it was not supposed to be done. Maxime will make sure not to do that again.

How does MPTCP (at the transport layer) compare with the feature of HTTP/3 QUIC streams (closer to the application layers) which can be transported over multiple paths?

QUIC doesn't support using multiple paths at the same time. There is a draft, some implementations support it, but the standardization is slow. The idea there is apparently to let apps manage the different paths themselves. More freedom, but more complex than just changing the socket protocol. QUIC does support connections migrations, but it is not as smooth as a seamless handover done by MPTCP, as only one path can be used at a time with QUIC for the moment.

To be clear, I would like to support MPTCP and this patch, but I have questions since I am not an expert in MPTCP. Before enabling this by default in lighttpd, I need to have a stronger understanding of potential implications and effects of doing so. Thank you.

We understand.
Having an option to support MPTCP is already good; having the possibility to use MPTCP directly with more servers would be even better, if the cost is small enough :)

Thank you for the detailed response.  I will be following the links and reading more about MPTCP in the coming days, so at this moment, I won't respond directly to your detailed comments.
In the meantime, I'd like to propose a practical approach to incrementally release these changes, even though the patch is small.  I propose that this patch be committed with the feature disabled by default config_feature_bool(srv, "server.network-mptcp", 0), and in the next lighttpd release, the release notes can announce a future scheduled behavior change where this feature will be enabled by default.  For example, there are a couple changes scheduled for the beginning of 2025 which were announced as part of the lighttpd 1.4.75 release: https://wiki.lighttpd.net/Release-1_4_75 .  By releasing this new feature disabled by default, it will allow others to more easily try it and report issues before the feature becomes enabled by default.
The next lighttpd release is likely some time in Q3 2024 time-frame unless bugs pop up or major feature development completes sooner, so announcing the change for the beginning of 2025 seems like a reasonable target to me.  I realize that may be disappointing, but lighttpd 1.4.75 was just recently released and I am attempting to get that into the next Ubuntu long-term release which is already in feature freeze.
In the details: On socket() with IPPROTO_MPTCP failure, log_pdebug() would be called once per listening socket at startup, e.g. for <IP_ADDRESS>:80 and [::]:80 and <IP_ADDRESS>:443 and [::]:443 and ...  While this occurs only at startup, it is noise and could be alarming to someone unfamiliar were the new feature suddently enabled by default.  Someone would have to change the lighttpd config to silence the trace.  Now then, it is generally good practice to check the return values from system calls.  In this case, if socket() with IPPROTO_MPTCP fails, MPTCP is probably disabled or unsupported, and the code will immediately try again with IPPROTO_TCP.  If that fails, an error is reported.  Therefore, I think the trace for IPPROTO_MPTCP can simply be removed, since it will probably not report any error of interest that failure with socket() with IPPROTO_TCP would not subsequently report.   If the feature is disabled by default, maybe the trace should remain for now, and later be removed when the feature is enabled by default?  I think that removing the trace is simplest.
  #ifdef __linux__
	if (config_feature_bool(srv, "server.network-mptcp", 0)) {
		/* manually define mptcp protocol number in case the compiler is using an older version of libc */
		#ifndef IPPROTO_MPTCP
		#define IPPROTO_MPTCP 262
		#endif
		srv_socket->fd = fdevent_socket_nb_cloexec(family, SOCK_STREAM, IPPROTO_MPTCP));
	}
	if (-1 != srv_socket->fd) { } else /*fallback to tcp*/
  #endif

Future looking: lighttpd mod_openssl and lighttpd mod_gnutls call uname() and check the linux kernel version for KTLS support.  Runtime feature checks could be performed at startup to test for IPPROTO_MPTCP support, which I would suggest if keeping the log_pdebug() trace is desired.  (I currently do not think the trace is needed, but can be convinced.)

@gstrauss thank you for your reply!

Thank you for the detailed response. I will be following the links and reading more about MPTCP in the coming days, so at this moment, I won't respond directly to your detailed comments.

All good, take your time!

In the meantime, I'd like to propose a practical approach to incrementally release these changes, even though the patch is small. I propose that this patch be committed with the feature disabled by default config_feature_bool(srv, "server.network-mptcp", 0), and in the next lighttpd release, the release notes can announce a future scheduled behavior change where this feature will be enabled by default. For example, there are a couple changes scheduled for the beginning of 2025 which were announced as part of the lighttpd 1.4.75 release: https://wiki.lighttpd.net/Release-1_4_75 . By releasing this new feature disabled by default, it will allow others to more easily try it and report issues before the feature becomes enabled by default.

It sounds like a good idea!
Should Maxime update some doc, and/or the default config file to reflect that?

The next lighttpd release is likely some time in Q3 2024 time-frame unless bugs pop up or major feature development completes sooner, so announcing the change for the beginning of 2025 seems like a reasonable target to me. I realize that may be disappointing, but lighttpd 1.4.75 was just recently released and I am attempting to get that into the next Ubuntu long-term release which is already in feature freeze.

That's OK, best not to rush anyway.

In the details: On socket() with IPPROTO_MPTCP failure, log_pdebug() would be called once per listening socket at startup, e.g. for <IP_ADDRESS>:80 and [::]:80 and <IP_ADDRESS>:443 and [::]:443 and ... While this occurs only at startup, it is noise and could be alarming to someone unfamiliar were the new feature suddently enabled by default. Someone would have to change the lighttpd config to silence the trace. Now then, it is generally good practice to check the return values from system calls. In this case, if socket() with IPPROTO_MPTCP fails, MPTCP is probably disabled or unsupported, and the code will immediately try again with IPPROTO_TCP. If that fails, an error is reported. Therefore, I think the trace for IPPROTO_MPTCP can simply be removed, since it will probably not report any error of interest that failure with socket() with IPPROTO_TCP would not subsequently report. If the feature is disabled by default, maybe the trace should remain for now, and later be removed when the feature is enabled by default? I think that removing the trace is simplest.

Good point, if MPTCP is used by default, it would probably be best not to warn the user multiple times. But if MPTCP has been explicitly enabled, should we not keep the log entry to let users understanding there was an issue? Or only warn them in case errno is ENOPROTOOPT, EPROTONOSUPPORT or EINVAL (linked to my previous comment: specific errors with MPTCP)?

Future looking: lighttpd mod_openssl and lighttpd mod_gnutls call uname() and check the linux kernel version for KTLS support. Runtime feature checks could be performed at startup to test for IPPROTO_MPTCP support, which I would suggest if keeping the log_pdebug() trace is desired. (I currently do not think the trace is needed, but can be convinced.)

Interesting, that could be used indeed, but please note that even if the kernel is recent enough (v5.6), MPTCP might still not be available: not compiled (CONFIG_MPTCP), disabled via a sysctl or SELinux, etc.
Please also note that MPTCP is currently not compatible with KTLS: they both use the same technique to extend TCP behaviour in the kernel (TCP ULP). Technically, it should be possible to chain these extensions, but that's not possible today (mainly because nobody requested it I think). I didn't know KTLS was used by default in lighttpd.

Good point, if MPTCP is used by default, it would probably be best not to warn the user multiple times. But if MPTCP has been explicitly enabled, should we not keep the log entry to let users understanding there was an issue? Or only warn them in case errno is ENOPROTOOPT, EPROTONOSUPPORT or EINVAL (linked to my previous comment: specific errors with MPTCP)?

In a world centered around MPTCP, yes that makes sense for you.  On the other hand, I do not think adding many lines of code around this is worthwhile as this is linux-specific and a simple strace() can be used to see if socket() with IPPROTO_MPTCP succeeds, or with what errno it fails.  MPTCP is a feature, and is not a critical failure if unavailable.

Future looking: lighttpd mod_openssl and lighttpd mod_gnutls call uname() and check the linux kernel version for KTLS support. Runtime feature checks could be performed at startup to test for IPPROTO_MPTCP support, which I would suggest if keeping the log_pdebug() trace is desired. (I currently do not think the trace is needed, but can be convinced.)

Interesting, that could be used indeed, but please note that even if the kernel is recent enough (v5.6), MPTCP might still not be available: not compiled (CONFIG_MPTCP), disabled via a sysctl or SELinux, etc.

lighttpd could at startup perform a single socket() with IPPROTO_MPTCP test and set a file-scoped static variable with whether or not IPPROTO_MPTCP is available, rather than checking uname() and sysctl and ...

Please also note that MPTCP is currently not compatible with KTLS: they both use the same technique to extend TCP behaviour in the kernel (TCP ULP). Technically, it should be possible to chain these extensions, but that's not possible today (mainly because nobody requested it I think). I didn't know KTLS was used by default in lighttpd.

Whether or not KTLS is enabled by default in lighttpd, that MPTCP and KTLS are not supported together should be carefully documented on the MPTCP site and this info shared with other projects to which your team sends patches.
What behavior/errors would someone see if they enabled MPTCP in lighttpd and also use lighttpd mod_openssl or lighttpd mod_gnutls with KTLS?  Would someone need to explicitly disable KTLS in order to use MPTCP?  Would someone need to explicitly disable MPTCP in order to use KTLS?  This interaction would need to be documented on the lighttpd wiki in both places where MPTCP will be documented, and where lighttpd TLS modules with KTLS are documented.
Unfortunately, MPTCP and KTLS not being supported together is a blocker for enabling MPTCP by default in lighttpd.
To keep progress moving, I am going to accept this patch, and will follow with another commit which makes some adjustments.

My commits will automatically close this PR, but I welcome continuing the conversation here or in another PR.

Future looking: lighttpd mod_openssl and lighttpd mod_gnutls call uname() and check the linux kernel version for KTLS support. Runtime feature checks could be performed at startup to test for IPPROTO_MPTCP support, which I would suggest if keeping the log_pdebug() trace is desired. (I currently do not think the trace is needed, but can be convinced.)

Interesting, that could be used indeed, but please note that even if the kernel is recent enough (v5.6), MPTCP might still not be available: not compiled (CONFIG_MPTCP), disabled via a sysctl or SELinux, etc.

lighttpd could at startup perform a single socket() with IPPROTO_MPTCP test and set a file-scoped static variable with whether or not IPPROTO_MPTCP is available, rather than checking uname() and sysctl and ...

Yes, it is better. (I don't know why I didn't think about that, that's usually what we recommend :) )

Please also note that MPTCP is currently not compatible with KTLS: they both use the same technique to extend TCP behaviour in the kernel (TCP ULP). Technically, it should be possible to chain these extensions, but that's not possible today (mainly because nobody requested it I think). I didn't know KTLS was used by default in lighttpd.

Whether or not KTLS is enabled by default in lighttpd, that MPTCP and KTLS are not supported together should be carefully documented on the MPTCP site and this info shared with other projects to which your team sends patches.

Yes, we forgot about the KTLS incompatibility, but we should and we will document this!
And we will check if it is possible to support both later on: https://github.com/multipath-tcp/mptcp_net-next/issues/480

What behavior/errors would someone see if they enabled MPTCP in lighttpd and also use lighttpd mod_openssl or lighttpd mod_gnutls with KTLS? Would someone need to explicitly disable KTLS in order to use MPTCP? Would someone need to explicitly disable MPTCP in order to use KTLS? This interaction would need to be documented on the lighttpd wiki in both places where MPTCP will be documented, and where lighttpd TLS modules with KTLS are documented.

For the moment, MPTCP and KTLS cannot work together. If you create an MPTCP socket, and you want to use KTLS, the setsockopt() call (setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));) will return an error. I'm sorry, I don't know how OpenSSL and GnuTLS handle that. Technically, it is easy to check try this setsockopt() and fall back if it is not available. We will investigate.

Unfortunately, MPTCP and KTLS not being supported together is a blocker for enabling MPTCP by default in lighttpd.

We understand.

To keep progress moving, I am going to accept this patch, and will follow with another commit which makes some adjustments.

Thank you for having accepted the patch, and for these adjustments!

Hi, after some testing, it appears that when MPTCP is enabled at the same time as KTLS. Since they are incompatible, KTLS returns a ENOPROTOOPT error and the SSL/TLS lib stays in user-space.
From a user point of view, the website works fine but KTLS was quietly ignored.
To be noted: This error does not occur in the lighttpd code but in the openssl library.

@mux99 thank you for confirming.  Yes, openssl will recover if KTLS is not available.  However, there will be a cost of one failed system call per connection to find that out.  Just FYI: attempting to avoiding that excess syscall is the reason I added the uname() check in lighttpd mod_openssl at lighttpd start up.


Impossible to re-connect

Hello, little bug on my side!
The 2FA is done correctly, with the generation of the backup keys.
Everything is fine.
If I log out and enter my password in the usual way, it tells me that my password is incorrect.
I'm obliged to enter forgotten password, and change the password to log in again.
And again, if I log out and try to log in, it doesn't work with the password!
(Another detail: when I put an image inside the QRCode, it simply doesn't generate and gives me an error).
Thanks for reading and have a nice day (thanks for the extension, it's really cool!) :)

(I'm on PHP 8.1.22)

Hello @RomualdYT
What version of the extension are you using? The latest is 1.0.10, but until 1.0.9 there was an issue with login sometimes that sounds like what you are describing here.
Firstly, please make sure you are on the latest version, and also ensure that you've cleared the Flarum cache php flarum cache:clear, and then hard refresh your browser. After this, everything should be fine 🤞

Thanks for the quick reply, that must be it! :)
But I'm in 1.0.7, I can't install via compose version 1.0.10, it only tells me that no other update is available :(

The error seemed to be mine, I managed to update, I'll try again :)

It's working, thanks !
Sorry for the loss of time

It's working, thanks !
Sorry for the loss of time

Great! No problem at all, happy to help :)


Settings to enable only audio  both

It would be a very important feature to have the option to either enable audio or both audio + video as a plugin settings that can applied application wide.  This is useful when we want to use the system just for audio call, and not always need video.

Just to make sure I don't have you wrong here: It sounds like you want one setting (let's say "audio-only") that is true or false, which completely disables video on the platform?

BTW it seems like at this point, the solution to #23 will cover this. Let's keep an eye on #23 from here.

@orblivion this is interesting

Ok... with the camera physically unplugged, but with a working microphone confirmed working live by the OS, I do not get the "allow video.etherpad.com to use your camera and microphone" request and the WebRTC column does not open.

With the microphone physically disabled but with the camera plugged in, I do get the prompt and can use the camera.

With what's now in master, based on my experience if I disable my camera and load the page it will give me a pop up error message telling me that there's no suitable camera. Did this person get that error message? (it may take a second or two)
Now, if you use my changes in #43, you can set "video_allowed": false in settings.json (i.e. admin decision), and it will only ask for microphone in the permissions prompt. I tried this with my camera disabled. Unlike before, it didn't stop me from starting a conversation (except in one version of Firefox where the microphone seemed to stay muted. Firefox is inconsistent and weird in general here.).
However, if I'm a user without a camera and the admin hasn't disabled video, my changes in #43 will not let me use the "video disabled on start" feature to only request a microphone, since "disabled" in this sense is like "muted". Video should still be ready to go; you should be able to turn the camera track on with a click.

Done via https://github.com/ether/ep_webrtc/pull/43 ?


ConvertJaxRsAnnotations doesn't replace Consumes and Produces annotations on class level

Describe the bug
ConvertJaxRsAnnotations replaces Consumes and Produces annotations on method level, but it doesn't replace these annotation on class level
SBM Version
0.14.1-SNAPSHOT
SBM Application
shell
To Reproduce
Steps to reproduce the behavior:

Go to PersonController (src/test/resources/testcode/bootify-jaxrs/src/main/java/com/example/jee/app/PersonController.java in module spring-shell)
Add @Produces("application/json") on class level
Run MigrateJaxRsAnnotationsRecipeIntegrationTest
The class is still annotated with javax.ws.rs.Produces

Expected behavior
The content-type is added to the RequestMapping annotation at class level.
Desktop (please complete the following information):
OS: Windows
Version 11 22H2

I'm fixing this issue in ConvertJaxRsAnnotations.


Comparison across differnet fields of a dict

I am not sure if this is currently possible, I have looked at the documentation and couldn't find an appropriate schema rule
if I have doc like  doc = {"a":1,"b":2,"c":1}
I need to check if doc["a"] == doc["b"]
Thanks.

i suggest using a custom validator.

@funkyfuture Thanks,Will try that.


[Remove Snap] TM ChainSafer

Description
Note: Removing a Snap from the registry means that users who have installed the Snap may continue to use it. New users will not be able to install the Snap.
Checklist
All items in the list below needs to be satisfied.

[ ] Is the reason for the removal documented in this issue?
[ ] Are the key parts of the communication with the developer to remediate the concerns documented in this issue?
[ ] The corresponding pull request in this repo has been merged.

The team behind this Snap has become unresponsive. We have not been able to get in touch with them for over 1 month.


Implement alternative timer styles

This might be relevant to @D4mnX 's interests
Working to implement alternative timer styles. Setup for boss bar and action bar.
TODO: configuration for choosing a style. BossBar requires 1.9, ActionBar requires ProtocolLib, maybe add a chat message as a 'catchall' fallback in case no available styles. Requires moving from the 'protocollib' only init block

To test on 1.8 + 1.9 later before merge

Needs a little bit more work to implement Bar Flags

Tested boss bar on 1.9, works fine.
Still to test:

[ ] action bar on 1.9

[ ] with protocollib
[ ] without protocollib

[ ] 1.8

Tested out bar flags, only fog seemed to have an effect really, don't think it's worth implementing just yet


Nested reducer, mapStateToProps, and ImmutableJS

Hey there. I'm using ImmutableJS (and therefore the /lib/immutable version of combineForms) and need some help sorting some things out.
Below is my nested reducer:
const createEvent = fromJS({
  comment: '',
  link: '',
});

export default function createReducer() {
  return combineReducers({
    report: combineReducers({
      summary: summaryReducer,
      components: componentsReducer,
    }),
    deep: combineForms({createEvent}, 'deep'),
  });
}

This JS is producing a state object like below:
{
  report: [Object]
  deep: {
    createEvent: [Map]
    forms: {
      $form: [Object]
      createEvent: {
        $form: [Object]
      }
    }
  }
}

This is mostly what I expect, but I'm not really sure if the createEvent Map is supposed to be there or what purpose it serves. I'd like to cut to the chase and just have the forms Object be a top-level item if possible but have not been successful in trying to do so.
Second, I am trying to selectively mapStateToProps in my Form component (so I'm only sending that part of the state to the component).
class CreateEvent extends Component {
   ...
}

function mapStateToProps(state) {
  return state.get('deep').toJS();
}

export default connect(mapStateToProps)(CreateEvent);

However, this is producing an error (no webpack errors, masked by a general error in the console). If I change deep to report instead, it works perfectly fine. I can't understand why I cannot retrieve this Object even though it appears in the state (as shown above).
Any assistance in getting everything to play nice would be hugely appreciated.

...I'd like to cut to the chase and just have the forms Object be a top-level item if possible but have not been successful in trying to do so.

Try using createForms instead of combineForms. Let's see if that solves the second problem as well.

Ah, nice. I think I tried that syntax, missed that it was createForms and not combineForms. That's producing the structure I was hoping for. Still an extra createEvent Object in the root, but I guess that's by design.
{
  createEvent: [Object]
  report: [Object]
  forms: {
    $form: [Object],
    createEvent: {
      $form: [Object],
      comment: [Object]
      link: [Object]
    }
  }
}

I solved my second problem by omitting the .toJS() transformation in the return statement. So, it seems forms is just a standard Object rather than an Immutable Map like it should be?

Yes, forms will always be a standard Object. RRF was created to work with most standard use-cases of React and Redux, and making form state an Immutable.JS Map would increase complexity and code size, which is unfavorable. Personally, I don't advocate using Immutable.JS - it's additional complexity and abstraction for very little gain in most use cases.

Understandable. I misunderstood what to expect with Immutable.JS compatibility. Unfortunately I'm forced to use a project boilerplate that uses it. But this will still work without .toJS in mapStateToProps and perhaps this thread will help someone else who might be make incorrect assumptions like me. Thanks!


Add composer details

Adds details to composer.json so this plugin can be listed on Packagist. After merging this in, please create an account on Packagist and list the plugin so that developers can install it via composer.

Thanks!

Added. https://packagist.org/packages/flynsarmy/oc-idehelper-plugin


Mapster in .NET 5 (C# 9.0)

Good afternoon. How does the library behave with records in .NET 5? I've noticed the tendency that the names of class and record fields should be strictly the same, and also use the same nesting of objects, even though we prescribe a behavior rule. Sometimes this is inconvenient. For example:
TypeAdapterConfig<a, aDTO>.NewConfig()
                          .Map(dest => dest.b, src => src.b)
                          .Map(dest => dest.c, src => src.c)
                              .Map(dest => dest.c.d.e, src => src.c.d.e)
                              .Map(dest => dest.c.d.f, src => src.c.d.f)

It just won't work any other way. And another question: what if you work with a model where an entity accepts parameters by constructor but gives them away by the usual get property?
Maybe there is some kind of guide to use in new environments? Thank you very much for the answer

There are a lot of questions, I cannot capture what is the issue. I will try to answer question by question.

How does the library behave with records in .NET 5?

Mapster should be able to map.

I've noticed the tendency that the names of class and record fields should be strictly the same, and also use the same nesting of objects, even though we prescribe a behavior rule. Sometimes this is inconvenient.

I cannot capture concern for this issue. If property names are the same, you don't need Map config.

what if you work with a model where an entity accepts parameters by constructor but gives them away by the usual get property?

I also cannot capture this, could you provide example? The model you described is similar to record types, so it should be able to map without config. (If property names are the same)

Maybe there is some kind of guide to use in new environments?

Wiki, or Sample projects, if you need more, feel free to contribute.


Footer social link fix (and others)

Currently, the links on the footer use nuxt-link, which gives them URLs like https://www.devwars.tv/http://www.twitch.tv/devwars, which leads to a 404 on the website, instead of the intended URL. This PR turns them into normal anchor tags, which should fix the issue. Also made sure to use https over http where possible

Oh, it looks like there's already a fix for this, so never mind. Should probably merge that one in pretty soon 😆


Load geometry from mapit and ensure shapes are clickable

We're loading metros and local munis.

Cool. I kind of get it 👍


[ci skip] adding user @xhochy

Hi! This is the friendly automated conda-forge-webservice.
I've added user @xhochy as instructed in #7.
Merge this PR to add the user. Please do not rerender this PR or change it in any way. It has [ci skip] in the commit message to avoid pushing a new build and so the build configuration in the feedstock should not be changed.
Please contact conda-forge/core to have this PR merged, if the maintainer is unresponsive.
Fixes #7

Merging this as part of the pdm fixes.


feat: depend on devserver binaries

Depend on devserver binaries instead of compiling from source. This won't require compilation of the go compiler when we start the dev server.
Once we merge this, we can release a new version and update the dependencies in the bazel package in angular/angular.
I went through several ideas on what would be the best way to distribute the binaries:

Upload the binaries to the repository and reference the filegroup in the //devserver_binaries package directly in ts_devserver.bzl https://github.com/bazelbuild/rules_typescript/pull/347/commits/b24f652399f4ac1ea3b60395a56afe2aa3c11418
(Current) Create a separate workspace with a build file which contains a filegroup. Create an archive for each release and distribute it in the release page https://github.com/bazelbuild/rules_typescript/pull/347/commits/0944bd7964fc6c085e32d29396f0848f8f0dfdd2

Drive by review (sorry). Is it possible to not upload the binaries in this repo? If you commit the binaries in git, the repo will get big quickly for people who want to depend on rules_typescript at a specific commit (a situation I find myself in regularly). These binaries clock in at ~ 5mb / binary / OS / release. There are 3 OSes per release and this repo has had 74 releases since its inception. Pretending that each of those releases had a new version of the binary compiled and uploaded in the repo, that would be an additional > 1gb of binary for me to download with only 5mb of it being useful, a < 0.5% signal to noise ratio.
Have you considered using something like Bazel toolchains to break the dependency? In the angular bazel repo, you could register a toolchain (or anyone in the dependency chain for that matter) that pulls a static binary from gstatic or downloads.google.com or even the releases page of github and leave a fallback that compiles the devserver when you're working from head. The rules_k8s team just finished toolchaining the kubectl binary, so I believe the starlark api is complete enough to support this usecase.

@achew22 thanks for the feedback! The binaries are not part of the repo. Here, you can find that I'm downloading them from a GitHub release.

Sorry about that. I looked at your first commit, which had the binaries checked in, and wanted to see if I could help out. The toolchain stuff is really really cool BTW. It's worth reading through the docs even just to see how the Bazel team conceptualizes toolchains.


feat(frontend): reuse PostMessageWalletData interface for BTC and IC

Motivation
The idea is to re-use wallet worker interfaces as much as possible. For now, BTC will have a separate type, but after I start working on adding transactions to the BTC worker, PostMessageDataResponseBtcWallet can be deleted.

Unrelated but, somehow related: we have to convert the post message types to Zod and add validations

@peterpeterparker good idea, noted 👍


feature: empty (value == None) data points in chart series

I need to generate a line chart in which one of the data points is missing. I want the line to be rendered with a "gap" that skips over the missing point.
I tried chart_data.add_series('East',    (24.3, "", 20.2)) but that didn't work.
Attaching an image what I am looking for.

How can I achieve this?

Are you able to achieve this when working manually with PowerPoint? If so, what do you do that produces the desired effect?

Hi Scanny,
In Powerpoint if I remove a value/point in excel then the line shown discontinued.
Attaching the same.

You can see I have removed the points for Category3, so in line chart line discontinued at Category3.
This is what I am looking for, is it possible to achieve using python-pptx?
Thanks,
Ankit Jain

Got it, thanks @ankitjain87, very helpful details.
We don't support empty (None) values in a series yet, but I'll leave this issue open as a feature request for that.

Thanks Scanny.

Added with v0.6.0 release uploaded to PyPI today.

Hello, What was the fix? I am trying soemthing very similar and python-pptx is treating None as 0.0


Do Not Disturb Mode?

can you give a quick example on how to watch for the event or status of Do Not Disturb mode and immediately send a command to turn it off?

I added a sample script to address this question.  Check it out!!


Add updater-v2.py which uses DigitalOcean API v2

Copied original updater.py and updated required areas to comply with the DO API v2. No other major alterations.

Thanks for the pull request, much appreciated!

And cheers for updating the readme.


operators dnext-operator (0.0.4)

Author Name Merih ilgor<EMAIL_ADDRESS>Signed-off-by: Merih ilgor<EMAIL_ADDRESS>Thanks submitting your Operator. Please check below list before you create your Pull Request.
New Submissions

[ ] Are you familiar with our contribution guidelines?
[ ] Have you packaged and deployed your Operator for Operator Framework?

[ ] Have you tested your Operator in all supported installation modes?
[ ] Have you considered whether you want use semantic versioning order?
[ ] Is your submission signed?
[ ] Is operator icon set?

Updates to existing Operators

[ ] Did you create a ci.yaml file according to the update instructions?
[x] Is your new CSV pointing to the previous version with the replaces property if you chose replaces-mode via the updateGraph property in ci.yaml?
[x] Is your new CSV referenced in the appropriate channel defined in the package.yaml or annotations.yaml ?
[x] Have you tested an update to your Operator when deployed via OLM?
[x] Is your submission signed?

Your submission should not

[x] Modify more than one operator
[x] Modify an Operator you don't own
[x] Rename an operator - please remove and add with a different name instead
[x] Modify any files outside the above mentioned folders
[x] Contain more than one commit. Please squash your commits.

Operator Description must contain (in order)

[x] Description about the managed Application and where to find more information
[x] Features and capabilities of your Operator and how to use it
[x] Any manual steps about potential pre-requisites for using your Operator

Operator Metadata should contain

[x] Human readable name and 1-liner description about your Operator
[x] Valid category name1
[x] One of the pre-defined capability levels2
[x] Links to the maintainer, source code and documentation
[x] Example templates for all Custom Resource Definitions intended to be used
[x] A quadratic logo

Remember that you can preview your CSV here.
--
1 If you feel your Operator does not fit any of the pre-defined categories, file an issue against this repo and explain your need
2 For more information see here

@merihilgor is it still a valid request? Then fix signature according to https://github.com/k8s-operatorhub/community-operators/pull/357/checks?check_run_id=4019504931

Feel free to reopen any time, we will assist you.


Event names getting overlapped It

Description of the problem
While I was trying to reproduce the issue in #130 in mne-tools/mne-qt-browser I saw that the event name are getting overlapped with each other
Steps to reproduce
# %%
import mne

sample_dir = mne.datasets.sample.data_path()
sample_fname = sample_dir / 'MEG' / 'sample' / 'sample_audvis_raw.fif'

raw = mne.io.read_raw_fif(sample_fname)
raw.crop(tmax=60)

events = mne.find_events(raw, stim_channel='STI 014')
event_id = {'auditory/left': 1, 'auditory/right': 2, 'visual/left': 3,
            'visual/right': 4, 'face': 5, 'buttonpress': 32}

raw.plot(events=events, event_id=event_id)

Link to data
No response
Expected results
It should have been consistent with the event duration like shown by @hoechenberger in the issue

Actual results

Additional information
none

I realized that as soon as I press - time button it the event name separates but I feel this issues can still be worked upon

What if we add a header and display the description there.
I think I could explain it better visually-

You will always be able to have long enough event names to overflow even in a dedicated area.

Yes it's definitely an issue; I wonder if we could detect the collision and display just a marker or truncated event description in that case, and only expose the full description on hover.

If this is possible I think a truncated version would be very nice! I'd truncate first, and if even that doesn't work (e.g. zoom out far enough) I'd remove the label completely.
Color-coding event types would be a good idea not just in that particular case – is this supported?

I'd like to second @cbrnr's proposal, I like that

Color-coding event types would be a good idea not just in that particular case – is this supported?

You can pass a dict with custom colors to ˋevent_colorˋ in raw.plot(). Or do you mean something else?

A qt-favoring solution in terms of simplicity might also be giving the event-labels a background with the color of the plot-background. If they stack you could at least read the one on top. And to expand we could intercept hoverEventˋ of [ˋEventLineˋ](https://github.com/mne-tools/mne-qt-browser/blob/e3fec001106fab34db0dc87f121f50dc278ddc40/mne_qt_browser/_pg_figure.py#L1380l) to put the hovered EventLine on top (ˋself.setZValue(1)ˋ). You find the code for the ˋInfiniteLineˋ from pyqtgraph which EventLine` inherits here.

You can pass a dict with custom colors to event_color in raw.plot(). Or do you mean something else?

Yes, but I meant the default behavior should be different colors for different events.


Question about rack2 and rails_6 appraisals

I found that rack2 and rails_6 files are running the same version as the rack2_2 and rails_6_1. Is it worth fixing ?

Probably yes.

Closed via https://github.com/ruby-grape/grape/pull/2225


Update az_span_scan_util logic and behavior.

Follow-up to feedback and conversation from https://github.com/Azure/azure-sdk-for-c/pull/1031
cc @vhvb1989

I'd like to stage the changes and merge this in first before https://github.com/Azure/azure-sdk-for-c/pull/1041, in case we want to bring this functionality back.


Make directory separators cross-friendly

Looks like they've been resolved much better on the latest commit


Make HTTP status 4xx responses uniform

Summary:
We were returning JSON for 429s, and HTML for 401s -- this PR has us return HTML for both.
I could've gone either way, but HTML is what delphi-epidata.R expects, and what I've been telling Dmitry, Logan, and Alex, so it won out.
I've confirmed that the headers set by the rate limiter are carried forward:
You can see that Retry-After is updated on sequential requests over the limit:
root@rinkitink:/usr0/home/krivard/projects/covid/driver# curl -is "http://localhost:10080/epidata/covidcast/meta?signal=jhu-csse:confirmed_incidence_num"
HTTP/1.1 429 TOO MANY REQUESTS
Server: meinheld/1.0.2
Date: Mon, 22 May 2023 20:59:03 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 233
X-My-Limit: 5
X-My-Remaining: 0
X-My-Reset:<PHONE_NUMBER>
Retry-After: 36
Connection: Keep-Alive

<!doctype html>

<title>429 Too Many Requests</title>

Too Many Requests

Rate limit exceeded for anonymous queries.
To remove this limit, register a free API key at https://forms.gle/hkBr5SfQgxguAfEt7

root@rinkitink:/usr0/home/krivard/projects/covid/driver# curl -is "http://localhost:10080/epidata/covidcast/meta?signal=jhu-csse:confirmed_incidence_num"
HTTP/1.1 429 TOO MANY REQUESTS
Server: meinheld/1.0.2
Date: Mon, 22 May 2023 20:59:06 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 233
X-My-Limit: 5
X-My-Remaining: 0
X-My-Reset:<PHONE_NUMBER>
Retry-After: 33
Connection: Keep-Alive

<!doctype html>

<title>429 Too Many Requests</title>

Too Many Requests

Rate limit exceeded for anonymous queries.
To remove this limit, register a free API key at https://forms.gle/hkBr5SfQgxguAfEt7

(I also fixed the name of an environment variable that was bugging me but that's not mandatory if we've already built stuff on top of that particular typo)
Prerequisites:

[x] It should be merged against the api-keys branch
[x] Branch is up-to-date with the branch to be merged with
[x] Build is successful
[x] Code is cleaned up and formatted

Don't merge until staging tests are clear


uhv: disable oghttp2 header validation when uhv is enabled

Commit Message: uhv: disable oghttp2 header validation when uhv is enabled
Additional Description: Disable header validation within oghttp2 when the UHV compiler flag is enabled
Risk Level: Low
Testing:
Docs Changes:
Release Notes:
Platform Specific Features:
Fixes: #21548
Fixes: #19751

CC @yanavlasov

/assign @yanavlasov

/retest

@ameily i think this probably needs a main merge - lets see...

/wait

@phlax I rebased on main. CI is failing a couple steps that I think just need to be run again.

linux coverage: //test/integration:tcp_tunneling_integration_test fails, but passes locally for me
windows: failed to download bazel

yep, looks like flakes - ill follow up on the first one - i think ive seen it elsewhere
/retest


Table not showing on dynamodb-local

Describe the bug
When using dynamodb-local on Mac OSX, a blank table is not displaying in GUI Client even though aws cli will display it
To Reproduce
Steps to reproduce the behavior:

Use Mac OSX and homebrew
Install dynamodb-local (brew cask install dynamodb-local)
Run dynamodb local, will default to localhost:8000, output shown:

$ dynamodb-local
Initializing DynamoDB Local with the following configuration:
Port:	8000
InMemory:	false
DbPath:	null
SharedDb:	false
shouldDelayTransientStatuses:	false
CorsParams:	*

Create a table. In my case it was a local node app creating the default example Music table:

     const profile = {
      region: 'us-west-2',
      endpoint: 'http://localhost:8000',
      convertEmptyValues: true,
    };

    const dynamoDb = new DynamoDB(profile);
    DynamoDB.DocumentClient(profile);

    const params = {
      AttributeDefinitions: [
        {
          AttributeName: 'Artist',
          AttributeType: 'S',
        },
        {
          AttributeName: 'SongTitle',
          AttributeType: 'S',
        },
      ],
      KeySchema: [
        {
          AttributeName: 'Artist',
          KeyType: 'HASH',
        },
        {
          AttributeName: 'SongTitle',
          KeyType: 'RANGE',
        },
      ],
      ProvisionedThroughput: {
        ReadCapacityUnits: 5,
        WriteCapacityUnits: 5,
      },
      TableName: 'Music',
    };

    return dynamoDb.createTable(params).promise();

With aws cli, conirm table exists:

aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": [
        "Music"
    ]
}

Connect to same localhost:8000 with Gui client, will always show "Empty database", even with refreshing on TABLES menu option.

Expected behavior
Should display created blank table
Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

OS: Mac OSX Mojave
node v8 to create table with code

Additional context
Add any other context about the problem here.

nevermind, user error -- my dynamodb did not have shared db turned on (and also no path on the db), so my node app and the GUI were seeing their own separate dynamo space instead of the same. Relaunching the dynamodb-local with sharedDb and a path fixed this.


Code coverage improvements

Can we improve the testing by increasing the code coverage?  The current status is:
-------------------------------|----------|----------|----------|----------|-------------------|
File                           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------------------------|----------|----------|----------|----------|-------------------|
All files                      |    23.43 |     1.66 |     0.49 |     25.3 |                   |
 hackathon-starter             |    83.89 |    18.18 |     6.67 |    83.89 |                   |
  app.js                       |    83.89 |    18.18 |     6.67 |    83.89 |... 13,217,221,229 |
 hackathon-starter/config      |     8.48 |        0 |        0 |      9.4 |                   |
  passport.js                  |     8.48 |        0 |        0 |      9.4 |... 48,549,550,552 |
 hackathon-starter/controllers |    14.49 |        0 |        0 |    15.73 |                   |
  api.js                       |    17.44 |        0 |        0 |    18.91 |... 32,634,635,640 |
  contact.js                   |    15.38 |        0 |        0 |    15.38 |... 60,61,62,64,65 |
  home.js                      |       50 |      100 |        0 |       50 |                 6 |
  user.js                      |    10.15 |        0 |        0 |    11.17 |... 70,372,376,379 |
 hackathon-starter/models      |    32.14 |        0 |        0 |       36 |                   |
  User.js                      |    32.14 |        0 |        0 |       36 |... 59,61,62,64,65 |
-------------------------------|----------|----------|----------|----------|-------------------|

I will add some unit tests, hopefully sometime this weekend, depending on my photo shoot plans, if not then next week. Although it’s kind of pointless to have a high code coverage since this is a boilerplate and not a production app, it could serve as a guide for writing tests, so it’s worth adding them.
To be honest, I haven’t done much Node.js testing since starting this project, but I did write thousands of test cases of various complexity using React/Redux/Redux-Saga/Jest/Enzyme apps for the past several years. I may end up refactoring some code though to make it more testable.

One set of tests that I think as far as maintenance could really come handy would be for the API pages, which there are quite a few of them.  Right now I have been mostly manually testing changes, and if it could be automated it would be great.  Also, can we have Github to run the tests on pull requests when they are submitted?  I recall a couple of cases that PRs seem to be OK but they ended up breaking the boilerplate right out of the box.  Having the automated tests on pull requests can provide quick and cheap feedback to submitters to fix the issues.

Probably what we need more of for the unit tests: https://mherman.org/blog/stubbing-http-requests-with-sinon.  My two cents would be to start from one of the OAuth or simpler API examples to try this.  Any kind of prerecorded http response is probably going to be sufficient.

Can I help u in increasing code coverage ?

@Sarvesh18 sure  PRs are welcome

Hey @YasharF , is this issue tagged for hacktoberfest 2021? And can I help in increasing the code coverage?


SyntheticUserAgentTelemetryInitializer return quickly if already done.

SyntheticUserAgentTelemetryInitializer, which, if called multiple times, will do all the compute-intensive task of checking useragent to the list of potential 'bot' strings.
https://github.com/Microsoft/ApplicationInsights-dotnet-server/blob/develop/Src/Web/Web.Shared.Net/SyntheticUserAgentTelemetryInitializer.cs#L50
This should return immediately if user agent is already compared.

wrong repo. opened in web.


🐞 [BUG] - Overlapping back button

Issue Verification

[X] I have verified that this is a new bug report.
[X] I'm interested in working on this issue
[X] I'm part of GSSOC organization

Describe the bug
Whenever a resource heading is clicked and user is directed to the particular page, the back button is conflicting with the logo. Also it works at the leftmost end of the back button only.
Here's a video:
https://github.com/jfmartinz/ResourceHub/assets/114223066/0b59df0f-b5ce-46c8-889e-51b58c2bc8ab
Expected behavior
To correct its alignment and make it work wherever it is clicked, not just at the left end.
I would like to work on this under Gssoc'24.
Steps to reproduce
No response
Additional Context
No response

@jfmartinz  Please assign this to me


move files to PluginStorage

This has been discussed in the discord but I don't see an issue for it here. It should be fairly simple to move the files over if they're detected outside of PluginStorage and start using the new folder within

I have a PR nearly ready for this, just needs a bit of testing, don't worry about it yet


Build icons for solid-js

Update build scripts to also generate icon components for solid-js with jsx syntax.

Hey thank you so much! I think for now this would best be handled as a third-party package, just because I don't want to commit to maintaining this ourselves going forward as none of the maintainers actively use Solid. Better for someone who would actually be using it to publish their own package and share it with the community, then it will actually be properly maintained 👍🏻
Sorry, hope that's understandable and thanks again regardless, really appreciate it.

Alright, will publish it as a third-party package then :)


Issue arrises when words in the class list are not in the dataset

First off, thanks for open sourcing the code!
I am trying to topic model with my own dataset. I set it up to look like the yelp dataset and modify the code accordingly. However, an error
Traceback (most recent call last):
  File "main.py", line 200, in <module>
    word_sup_array = np.array([np.array([vocabulary[word] for word in word_class_list]) for word_class_list in word_sup_list])
  File "main.py", line 200, in <listcomp>
    word_sup_array = np.array([np.array([vocabulary[word] for word in word_class_list]) for word_class_list in word_sup_list])
  File "main.py", line 200, in <listcomp>
    word_sup_array = np.array([np.array([vocabulary[word] for word in word_class_list]) for word_class_list in word_sup_list])
KeyError: 'algebra_and_number_theory'

is thrown on the following line:
https://github.com/yumeng5/WeSTClass/blob/70d8780a17c36afde63d477d44538833ffffe87b/main.py#L194
It looks like this is because one of my provided class names (algebra_and_number_theory) in ${dataset}/classes.txt is not contained within the vocabulary.
I am confused as to wether this is my fault or a bug in the code? I wouldn't expect class names to be in the vocabulary, so I am leaning toward the latter. In either case, any help would be much appreciated!

Hi John,
The error is expected if the provided class label surface name is not in the vocabulary, in which case the class name will not appear in the word embedding trained on the corpus, and there is no way to represent the class name as a word vector for all subsequent tasks.
Here are some possible solutions for this:

Change the type of weak supervision. The algorithm also supports the use of class-related keywords as supervision. For example, if the class name is algebra_and_number_theory, you may come up with some related word tokens as supervision, such as algebra, arithmetic  and number. The ideal choice of keywords would be those that can distinguish the target class from all other classes.
Use some phrase mining tool to detect phrases and pre-process the corpus. The current algorithm trains word embedding for each single word token. Specifically, if a phrase algebra and number theory appears in the corpus, it will not be treated as a phrase, and each word's embedding will be trained independently. You can try to connect these words with underscore characters so that the algorithm treats phrases as a whole. If the number of classes is small, you can even try to manually construct phrases for class names only.
Use pre-trained embedding instead of training the embedding on your current corpus. Some available pre-trained embedding might contain phrases and/or out vocabulary words. You will need to modify the function train_word2vec in main.py to load pre-trained embedding. You might also need to manually add the class names into the variable vocabulary in main.py.

I am not sure which of the solutions work best in your case, but I would suggest trying 1 and 2 first, because pre-trained word embedding (3) may not suit your corpus well.

Thanks for the detailed response!
My class labels are almost all multiple tokens long. So I think that I will split them into individual tokens, drop any stop words, and then simply use these lists of tokens as keywords (my sup_source).
Hopefully that works. Thanks again!


Another optimization suggestion for Resize()

This is a bit bold, but works nice for your algorithm. It is up to you if you want to amend it or not.
I have noticed that after the allocation of the new metadata array, you immediately initialize it with the emptyBucket value (-127). So basically the array is initialized twice - once with zeros (using new) and then with -127. Also, the entries array is never used in the code without first checking the metadata array (well, except for the IndexOf() method which is for testing purposes, but it also can be amended to make metadata lookups first)
https://github.com/Wsm2110/Faster.Map/blob/9c60000c53e0bad32b9130a5b3297ec9f259e4d2/src/DenseMapSIMD.cs#L762-L765
So basically we can safely allocate both arrays without initializing them to zero (you don't rely on those zeros in the code anyway) using GC.AllocateUninitializedArray. I have tested it and allocation of array of 1_000_000 ints without initialization is about 11 times faster.
 _metadata = GC.AllocateUninitializedArray<sbyte>((int)_length + 16);
 _entries = GC.AllocateUninitializedArray<Entry<TKey, TValue>>((int)_length + 16);

This brings also slight improvement to the final AddAndResize benchmark. Let me know what you think!
P.S.
If you don't like that the following line starts with new
new Span<sbyte>(_metadata).Fill(_emptyBucket);
the following is equivalent
_metadata.AsSpan().Fill(_emptyBucket);

LOL, I just figured out that we don't need to copy/clone those arrays at all
https://github.com/Wsm2110/Faster.Map/blob/9c60000c53e0bad32b9130a5b3297ec9f259e4d2/src/DenseMapSIMD.cs#L759-L763
We don't use them anymore. Right on the next line we erase the variables. So we can just copy the references
 var oldEntries = _entries;
 var oldMetadata = _metadata;

 _metadata = new sbyte[_length + 16];
 _entries = new Entry<TKey, TValue>[_length + 16];

My suggestion in the previous comment still stands though :)

hi mate, love these suggestions.  Keep'em coming


Support for outputting ES format Modules

Addresses #5.
Not complete, but wanted to start getting a few eyes on it.
Notably, the following works.
import {yay} from './import-this';

export function exported(argument) {
  console.log(argument);
  console.log(yay);
}

export function exported(a){console.log(a);console.log(1)};

Just a question - does the code allow for keeping things as external?

@Andarist What do you mean as external? I am not following.

I mean the external option of rollup. Keeping dependencies as dependencies - flat bubdling only own code. Use case - building libraries with dependencies rather than app

Thanks @Andarist – will take a look at the external option in a separate issue/PR. Would like to ensure there is a valid test suite to ensure it's working as expected.

@prateekbh – This is ready for another look, addressed feedback from earlier in person review.
Thanks again to everyone taking a look!


TB4 cameras not working

I cannot get the cameras working. Please advise.
I tried
ubuntu@ubuntu:~$ ros2 launch turtlebot4_bringup oakd.launch.py
which resulted in the following error message:
[INFO] [launch]: All log files can be found below /home/ubuntu/.ros/log/2022-11-20-03-53-57-055146-ubuntu-1485
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rgb_stereo_node-1]: process started with pid [1487]
[rgb_stereo_node-1] terminate called after throwing an instance of 'std::runtime_error'
[rgb_stereo_node-1]   what():  No available devices
[rgb_stereo_node-1] Stack trace (most recent call last):
[rgb_stereo_node-1] #11   Object "/opt/ros/galactic/lib/depthai_examples/rgb_stereo_node", at 0xaaaae4008d37, in
[rgb_stereo_node-1] #10   Object "/lib/aarch64-linux-gnu/libc.so.6", at 0xffff8104de0f, in __libc_start_main
[rgb_stereo_node-1] #9    Object "/opt/ros/galactic/lib/depthai_examples/rgb_stereo_node", at 0xaaaae4007ce7, in
[rgb_stereo_node-1] #8    Object "/opt/ros/galactic/lib/aarch64-linux-gnu/libdepthai-core.so", at 0xffff815951f3, in dai::Device::Device(dai::Pipeline const&)
[rgb_stereo_node-1] #7    Object "/opt/ros/galactic/lib/aarch64-linux-gnu/libdepthai-core.so", at 0xffff815a730f, in dai::DeviceBase::DeviceBase(dai::OpenVINO::Version)
[rgb_stereo_node-1] #6    Object "/opt/ros/galactic/lib/aarch64-linux-gnu/libdepthai-core.so", at 0xffff8159d7e7, in dai::DeviceBase::tryGetDevice()
[rgb_stereo_node-1] #5    Object "/lib/aarch64-linux-gnu/libstdc++.so.6", at 0xffff81263573, in __cxa_throw
[rgb_stereo_node-1] #4    Object "/lib/aarch64-linux-gnu/libstdc++.so.6", at 0xffff8126327f, in std::terminate()
[rgb_stereo_node-1] #3    Object "/lib/aarch64-linux-gnu/libstdc++.so.6", at 0xffff8126321b, in
[rgb_stereo_node-1] #2    Object "/lib/aarch64-linux-gnu/libstdc++.so.6", at 0xffff812658cb, in __gnu_cxx::_verbose_terminate_handler()
[rgb_stereo_node-1] #1    Object "/lib/aarch64-linux-gnu/libc.so.6", at 0xffff8104daab, in abort
[rgb_stereo_node-1] #0    Object "/lib/aarch64-linux-gnu/libc.so.6", at 0xffff81060d78, in gsignal
[rgb_stereo_node-1] Aborted (Signal sent by tkill() 1487 1000)
[ERROR] [rgb_stereo_node-1]: process has died [pid 1487, exit code -6, cmd '/opt/ros/galactic/lib/depthai_examples/rgb_stereo_node --ros-args --params-file /tmp/launch_params_8ck821ib --params-file /tmp/launch_params_s4346vbw --params-file /tmp/launch_params_185e583r --params-file /tmp/launch_params_3l741p98 --params-file /tmp/launch_params_utc5x_jq --params-file /tmp/launch_params_g62vq4f3 --params-file /tmp/launch_params_7orrfo9l --params-file /tmp/launch_params_32cmpp0 --params-file /tmp/launch_params_7pui7c3i --params-file /tmp/launch_params_9inj9esh --params-file /tmp/launch_params_5ywqa6z7 --params-file /tmp/launch_params_7f_9ol5y --params-file /tmp/launch_params_jrjfab0y --params-file /tmp/launch_params__jxxgrmf'].
I also tried
ubuntu@ubuntu:~$ ros2 launch depthai_examples mobile_publisher.launch.py
which resulted in the following error message.
[INFO] [launch]: All log files can be found below /home/ubuntu/.ros/log/2022-11-21-22-13-34-244676-ubuntu-1490
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [mobilenet_node-1]: process started with pid [1493]
[INFO] [robot_state_publisher-2]: process started with pid [1495]
[robot_state_publisher-2] Link oak-d_frame had 5 children
[robot_state_publisher-2] Link oak_imu_frame had 0 children
[robot_state_publisher-2] Link oak_left_camera_frame had 1 children
[robot_state_publisher-2] Link oak_left_camera_optical_frame had 0 children
[robot_state_publisher-2] Link oak_model_origin had 0 children
[robot_state_publisher-2] Link oak_rgb_camera_frame had 1 children
[robot_state_publisher-2] Link oak_rgb_camera_optical_frame had 0 children
[robot_state_publisher-2] Link oak_right_camera_frame had 1 children
[robot_state_publisher-2] Link oak_right_camera_optical_frame had 0 children
[robot_state_publisher-2] [INFO] [1669068815.447841295] [oak_state_publisher]: got segment oak-d-base-frame
[robot_state_publisher-2] [INFO] [1669068815.448166718] [oak_state_publisher]: got segment oak-d_frame
[robot_state_publisher-2] [INFO] [1669068815.451300333] [oak_state_publisher]: got segment oak_imu_frame
[robot_state_publisher-2] [INFO] [1669068815.451395536] [oak_state_publisher]: got segment oak_left_camera_frame
[robot_state_publisher-2] [INFO] [1669068815.451514794] [oak_state_publisher]: got segment oak_left_camera_optical_frame
[robot_state_publisher-2] [INFO] [1669068815.451575256] [oak_state_publisher]: got segment oak_model_origin
[robot_state_publisher-2] [INFO] [1669068815.451621274] [oak_state_publisher]: got segment oak_rgb_camera_frame
[robot_state_publisher-2] [INFO] [1669068815.451656255] [oak_state_publisher]: got segment oak_rgb_camera_optical_frame
[robot_state_publisher-2] [INFO] [1669068815.451689014] [oak_state_publisher]: got segment oak_right_camera_frame
[robot_state_publisher-2] [INFO] [1669068815.451722921] [oak_state_publisher]: got segment oak_right_camera_optical_frame
[mobilenet_node-1] [18443010E197631200] [200.730] [system] [error] Attempted to start Color camera - NOT detected!

I used the extra USB-A to USB-C cable sent with the TB4.
ubuntu@ubuntu:~$ ros2 launch turtlebot4_bringup oakd.launch.py gives the same error message as the one I first sent you - No available devices.

I checked the USB-C and it did not have a good connection. I removed the camera and tried again. Same error:
ubuntu@ubuntu:~$ ros2 launch turtlebot4_bringup oakd.launch.py
[INFO] [launch]: All log files can be found below /home/ubuntu/.ros/log/2022-11-22-18-27-51-496749-ubuntu-1844
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rgb_stereo_node-1]: process started with pid [1846]
[rgb_stereo_node-1] [18443010E197631200] [23.599] [system] [error] Attempted to start Color camera - NOT detected!
[rgb_stereo_node-1] [18443010E197631200] [23.599] [system] [error] Attempted to start Mono Left camera - NOT detected!
[rgb_stereo_node-1] [18443010E197631200] [23.599] [system] [error] Attempted to start Mono Right camera - NOT detected!

Just to be safe can you try this:

Unplug the USB-C again
Disable the turtlebot4 service - sudo systemctl disable turtlebot4
Reboot the RPi - sudo reboot
Wait for SSH session to reconnect
Plug the camera back in and run ros2 launch turtlebot4_bringup oakd.launch.py

Went through your list with the new cable. Same error:
ubuntu@ubuntu:~$ ros2 launch turtlebot4_bringup oakd.launch.py
[INFO] [launch]: All log files can be found below /home/ubuntu/.ros/log/2022-11-22-19-59-50-456904-ubuntu-1314
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rgb_stereo_node-1]: process started with pid [1316]
[rgb_stereo_node-1] [18443010E197631200] [25.979] [system] [error] Attempted to start Color camera - NOT detected!
[rgb_stereo_node-1] [18443010E197631200] [25.979] [system] [error] Attempted to start Mono Left camera - NOT detected!
[rgb_stereo_node-1] [18443010E197631200] [25.979] [system] [error] Attempted to start Mono Right camera - NOT detected!

@bld7

is this OAK-D-Lite or OAK-D-Pro ?
Can you run the launch command with a prefix of DEPTHAI_LEVEL=debug and share the logs please ?

We bought a standard TB4, so it should be an OAK-D-Pro.
I executed the command:
ubuntu@ubuntu:~$ ros2 launch turtlebot4_bringup oakd.launch.py DEPTHAI_LEVEL:=debug
[INFO] [launch]: All log files can be found below /home/ubuntu/.ros/log/2022-11-23-19-32-35-886942-ubuntu-1361
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [rgb_stereo_node-1]: process started with pid [1363]
[rgb_stereo_node-1] [18443010E197631200] [283.076] [system] [error] Attempted to start Color camera - NOT detected!
[rgb_stereo_node-1] [18443010E197631200] [283.076] [system] [error] Attempted to start Mono Left camera - NOT detected!
[rgb_stereo_node-1] [18443010E197631200] [283.076] [system] [error] Attempted to start Mono Right camera - NOT detected!
Killed with Ctrl-C
Log file contents:
ubuntu@ubuntu:~/.ros/log/2022-11-23-19-36-31-960629-ubuntu-1395$ more launch.log
1669232191.9693925 [INFO] [launch]: All log files can be found below /home/ubuntu/.ros/log/2022-11-23-19-36-31-960629-ubuntu-1395
1669232191.9702470 [INFO] [launch]: Default logging verbosity is set to INFO
1669232192.7112648 [INFO] [rgb_stereo_node-1]: process started with pid [1397]
1669232225.9028938 [WARNING] [launch]: user interrupted with ctrl-c (SIGINT)
1669232227.0280821 [INFO] [rgb_stereo_node-1]: process has finished cleanly [pid 1397]

@bld7 Can you try launching it like this: DEPTHAI_LEVEL=debug ros2 launch turtlebot4_bringup oakd.launch.py?

The terminal output is given in the attached file.
terminal_output.txt

@saching13 Do you see anything in the logs that would help?

The content for the two log files I found are:
ubuntu@ubuntu:~/.ros/log/2022-11-28-18-45-05-765776-ubuntu-1720$ more launch.log
1669661105.7743659 [INFO] [launch]: All log files can be found below /home/ubuntu/.ros/log/2022-11-28-18-45-05-765776-ubuntu
-1720
1669661105.7752223 [INFO] [launch]: Default logging verbosity is set to INFO
1669661106.5147333 [INFO] [rgb_stereo_node-1]: process started with pid [1722]
1669661143.9237084 [WARNING] [launch]: user interrupted with ctrl-c (SIGINT)
1669661145.0544739 [INFO] [rgb_stereo_node-1]: process has finished cleanly [pid 1722]
and
ubuntu@ubuntu:~/.ros/log$ more rgb_stereo_node_1722_1669661106701.log
[INFO] [1669661143.922794789] [rclcpp]: signal_handler(signal_value=2)

Ever since I executed the  commands suggested earlier:
Unplug the USB-C again
Disable the turtlebot4 service - sudo systemctl disable turtlebot4
Reboot the RPi - sudo reboot
Wait for SSH session to reconnect
Plug the camera back in and run ros2 launch turtlebot4_bringup oakd.launch.py

The LCD display and LEDs above the display are dark. Plus a number of nodes are not starting up, for example the nodes
/turtlebot4_base_node
/turtlebot4_diagnostics
/turtlebot4_node
What should I do to resolve these problems?

@bld7 You can run sudo systemctl enable turtlebot4 to re-enable the service, then sudo systemctl start turtlebot4 to start it up.

@bld7  sorry for the delay. Can you run this script and share the dump from it ?
it looks like some new config we added might be missing.
And also can you check which version of depthai is used here ?

I tried running the script, but it cannot find the module depthai. How do I go about running the script?
The version of depthai is 2.15.4 (taken from packge.xml).

See the attached file for the script output.
calibration_dump_terminal_output.txt

looks like depthai-core version is old. it should be 2.17+ for that configuration.
can you try installing the newest version using ros-<dist>depthai

Can you send me full error ?
And try with stereo_inertial_node too

Attached is the output from
ros2 launch -d turtlebot4_bringup oakd.launch.py
and
ros2 launch -d depthai_examples stereo_inertial_node.launch.py
oakd_debug_output.txt

ros2 launch -d turtlebot4_bringup oakd.launch.py on this can you do this instead DEPTHAI_LEVEL=debug ros2 launch turtlebot4_bringup oakd.launch.py
ros2 launch -d depthai_examples stereo_inertial_node.launch.py it looks like working. Crash seems to be because of RVIZ in it. WHich can be disabled by adding argument  enableRviz=false

The output from
DEPTHAI_LEVEL=debug ros2 launch turtlebot4_bringup oakd.launch.py
and
ros2 launch -d depthai_examples stereo_inertial_node.launch.py enableRviz:=false
is attached in the file.
oakd_output_dec10_2022.txt

@bld7 At this point I would recommend re-installing the RPI image by following the instructions here https://turtlebot.github.io/turtlebot4-user-manual/overview/quick_start.html#install-latest-raspberry-pi-image.

@bld7  looks like the issue was rviz2 package not being there. I added additional condition to remove that on the stereo_inertial_node here Can you try it out and let me know if it fixes the problem ?

@roni-kreinin I re-installed the latest RPI image. Executing ros2 launch turtlebot4_bringup oakd.launch.py still produced an error. See the attached file.
output_after_rpi_image_reinstall.txt

@bld7 Try running the following to fix the udev rules:
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

@saching13 The stereo_inertial_node.launch.py file had a number of differences compared to your new one, so I copied your complete file.  The output from
DEPTHAI_LEVEL=debug ros2 launch turtlebot4_bringup oakd.launch.py
and
ros2 launch -d depthai_examples stereo_inertial_node.launch.py enableRviz:=false
are attached. Note that I put in the original RPI sd card to continue with where we left off earlier.
stereo_inertial_launch_output.txt
oakd_launch_output.txt

@roni-kreinin  I executed the udev rule fix you sent using the new RPI image. The ros2 launch turtlebot4_bringup oakd.launch.py output and the DEPTHAI_LEVEL=debug ros2 launch turtlebot4_bringup oakd.launch.py ouput are attached. Note that I had this same error last year with the old image, and at that time I tried the same udev rules fix from the luxonis site.
udev_rules_fix_output.txt

[rgb_stereo_node-1]   what():  Failed to connect to device, error message: X_LINK_DEVICE_ALREADY_IN_USE

It looks like there might be another node already running which connected to the device.

Closing as stale.


[BOW-98] Fix flaky E2E test

Codecov Report
Patch coverage has no change and project coverage change: +3.19% :tada:

Comparison is base (2293051) 14.82% compared to head (40285d2) 18.02%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #68      +/-   ##
==========================================
+ Coverage   14.82%   18.02%   +3.19%
==========================================
  Files         146       37     -109
  Lines       11314     4728    -6586
  Branches      282      119     -163
==========================================
- Hits         1677      852     -825
+ Misses       9637     3876    -5761

see 109 files with indirect coverage changes

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


Add integration tests for other Java EE / Jakarta EE servers

The EE integration for rest-problem-java is currently only used and tested on JBoss EAP.
We should add integration tests for some other Java EE / Jakarta EE servers too.
But we better focus on those application servers that are actually used by the institutions that implement the Belgif guidelines.
@pvdbosch are any other java application servers used at Smals?
@VirginieHayot and at eHealth?
@barthanssens  and at BOSA?
others?

We're not using any other app servers currently for significant new application development.


Unrecognized command: define-eval

when i run crox train.crox.prototxt > train.prototxt, error happen:

ERROR globals.crox:2 Unrecognized command: define-eval

why? can anybody help me?

Sorry about that, this function was still sitting on my computer. It has been pushed to the crox repository and the version has been updated. If you installed it through pip, pip install -U crox should be enough to fix this.