knapsack:rspec passing in --fail-fast option?

Hi,
We are using knapsack on Semaphore CI and loves it. When our dev push their branches, we ran parallel tests on the suite, but for each test, we also want it to have --fail-fast option, stop running test on first failing test. How can I pass in that option?
Thanks.

Looks like I can do this:
bundle exec rake "knapsack:rspec[--fail-fast]"


Cannot run terragrunt plan with same -out path twice

Describe the bug
Running terragrunt plan -out="/tmp/tgplan.tf" twice from the same folder, results in an infinite loop error.
To Reproduce
create a valid terragrunt folder and run terragrunt plan -out="/tmp/tgplan.tf" twice
Expected behavior
The plan to be overwritten
Nice to have
Terminal output of creating the plan successfully:
ζ ls                                                                                [34829c0]
dev            terragrunt.hcl
# M1: ~/Documents/git/aws/infra/kms <feature/issue-334/terraform-restructure ✘ [*?]>                                       (14:22:08)
ζ terragrunt plan -out="$(pwd)/tgplan.tf"                                                                                [34829c0]
module.kms_ebs.module.kms.data.aws_caller_identity.current: Reading...
module.account_context.data.aws_region.current: Reading...
module.kms_rds[0].module.kms.data.aws_caller_identity.current: Reading...
module.kms_sns.module.kms.data.aws_caller_identity.current: Reading...
module.kms_ebs.data.aws_region.current: Reading...
module.kms_rds[0].data.aws_region.current: Reading...
module.kms_sns.module.kms.data.aws_partition.current: Reading...
(...)
long plan output here
(...)
    }

╷
│ Warning: Experimental feature "module_variable_optional_attrs" is active
│
│   on ../../../modules/aws/kms/versions.tf line 12, in terraform:
│   12:   experiments = [module_variable_optional_attrs]
│
│ Experimental features are subject to breaking changes in future minor or
│ patch releases, based on feedback.
│
│ If you have feedback on the design of this feature, please open a GitHub
│ issue to discuss it.
│
│ (and 2 more similar warnings elsewhere)
╵

─────────────────────────────────────────────────────────────────────────────

Saved the plan to: /Users/user01/Documents/git/aws/infra/kms/tgplan.tf

To perform exactly these actions, run the following command to apply:
    terraform apply "/Users/user01/Documents/git/aws/infra/kms/tgplan.tf"
Releasing state lock. This may take a few moments...
# M1: ~/Documents/git/aws/infra/kms <feature/issue-334/terraform-restructure ✘ [*?]>                                       (14:22:21)
ζ ls                                                                                [34829c0]
dev            terragrunt.hcl tgplan.tf

If I run again terragrunt plan -out="$(pwd)/tgplan.tf" (or terragrunt plan alone for that matter), I get this:

as if it is trying to do something with the binary file
Versions

Terragrunt version: terragrunt version v0.46.3
Terraform version: Terraform v1.2.9
Environment details (Ubuntu 20.04, Windows 10, etc.):  M1 Ventura 13.4

Additional context
Doesn't matter if I try to change the path, no matter what I enter I get the same error

Hi,
looks suspicious that the plan is saved in a file with .tf extension - terraform will try to load and apply all .tf files...
From Terraform documentation https://developer.hashicorp.com/terraform/cli/commands/plan :

Do not name the file with a suffix that Terraform recognizes as another file format; if you use a .tf suffix then Terraform will try to interpret the file as a configuration source file, which will then cause syntax errors for subsequent commands.

I would suggest first to try different extension, like .plan


CPU utilization is not 100%

Windows Build Number
Microsoft Windows [Version 10.0.19042.928]
WSL Version

[X] WSL 2
[ ] WSL 1

Kernel Version
4.19.128-microsoft-standard
Distro Version
Ubuntu 18.04
Other Software
No response
Repro Steps
On a system using Threadripper 1950X with NUMA enabled (16 cores - 32 threads with SMT), install and run sysbench;
sysbench cpu --threads=32 run. wsl config;
[wsl2]
memory=8GB
processors=16

Expected Behavior
100% CPU utilization on Windows Task Manager
Actual Behavior
Instead it does not exceed ~65% (There are other things working at the time of benchmark, this is probably near 50%). All cores seem to get involved in the process but they never hit 100% utilization during the benchmark. The wsl instance thinks it is using 100% CPU (e.g w.r.t htop)
Output of lscpu;
Architecture:        x86_64
CPU op-mode(s):      32-bit, 64-bit
Byte Order:          Little Endian
CPU(s):              16
On-line CPU(s) list: 0-15
Thread(s) per core:  2
Core(s) per socket:  8
Socket(s):           1
Vendor ID:           AuthenticAMD
CPU family:          23
Model:               1
Model name:          AMD Ryzen Threadripper 1950X 16-Core Processor
Stepping:            1
CPU MHz:             3393.655
BogoMIPS:            6787.31
Hypervisor vendor:   Microsoft
Virtualization type: full
L1d cache:           32K
L1i cache:           64K
L2 cache:            512K
L3 cache:            8192K
Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm rep_good nopl cpuid extd_apicid pni pclmulqdq ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm cmp_legacy cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw topoext ssbd ibpb vmmcall fsgsbase bmi1 avx2 smep bmi2 rdseed adx smap clflushopt sha_ni xsaveopt xsavec xgetbv1 xsaves clzero xsaveerptr virt_ssbd arat

Diagnostic Logs

/dupe #5423


Fix error messages that contain "(" from being parsed incorrectly

Fixes https://github.com/feross/snazzy/issues/14

Merged, but please review. I may have made a mistake and could use an extra set of eyes. Regexes are always tricky.

Released as 1.0.2

Cool will check in the morning. Go to bed! :)

@Flet On it! 😴


PubSub: NullPointerException at com.google.apphosting.runtime.ApiProxyImpl$CurrentRequestThreadFactory.newThread(ApiProxyImpl.java:1267)

After upgrading my PubSub client to 0.20.3-beta (as well as a few other Google dependencies) and switching from the Java8 flexible environment to the Java8 standard environment I'm no longer able to publish messages to my PubSub topic.  I'm seeing this error in the logs for my AppEngine standard Java8 environment after publishing a message and get()ing the Future:
io.grpc.internal.ChannelExecutor drain: Runnable threw exception in ChannelExecutor (ChannelExecutor.java:89)
java.lang.NullPointerException
	at com.google.apphosting.runtime.ApiProxyImpl$CurrentRequestThreadFactory.newThread(ApiProxyImpl.java:1267)
	at com.google.common.util.concurrent.ThreadFactoryBuilder$1.newThread(ThreadFactoryBuilder.java:162)
	at java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:612)
	at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:925)
	at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1587)
	at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:336)
	at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:555)
	at io.grpc.internal.ManagedChannelImpl.rescheduleIdleTimer(ManagedChannelImpl.java:334)
	at io.grpc.internal.ManagedChannelImpl.exitIdleMode(ManagedChannelImpl.java:299)
	at io.grpc.internal.ManagedChannelImpl$4$1.run(ManagedChannelImpl.java:357)
	at io.grpc.internal.ChannelExecutor.drain(ChannelExecutor.java:87)
	at io.grpc.internal.ManagedChannelImpl$4.get(ManagedChannelImpl.java:359)
	at io.grpc.internal.ClientCallImpl.start(ClientCallImpl.java:218)
	at io.grpc.ForwardingClientCall.start(ForwardingClientCall.java:47)
	at com.google.api.gax.grpc.HeaderInterceptor$1.start(HeaderInterceptor.java:62)
	at io.grpc.stub.ClientCalls.startCall(ClientCalls.java:276)
	at io.grpc.stub.ClientCalls.asyncUnaryRequestCall(ClientCalls.java:252)
	at io.grpc.stub.ClientCalls.futureUnaryCall(ClientCalls.java:186)
	at com.google.pubsub.v1.PublisherGrpc$PublisherFutureStub.publish(PublisherGrpc.java:460)
	at com.google.cloud.pubsub.v1.Publisher.publishOutstandingBatch(Publisher.java:329)
	at com.google.cloud.pubsub.v1.Publisher.publishAllOutstanding(Publisher.java:304)
	at com.google.cloud.pubsub.v1.Publisher.access$500(Publisher.java:79)
	at com.google.cloud.pubsub.v1.Publisher$5.run(Publisher.java:283)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:295)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

I'm using a Gradle build with the following relevant dependencies:
dependencies {
  providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
  providedCompile 'com.google.appengine:appengine:+'
  testCompile 'org.eclipse.jetty:jetty-server:9.+'
  testCompile 'org.eclipse.jetty:jetty-servlet:9.+'
  compile group: 'com.google.guava', name: 'guava', version: '19.+'
  compile group: 'com.google.inject', name: 'guice', version: '4.+'
  compile 'com.google.appengine:appengine-api-1.0-sdk:1.+'
  compile 'com.google.cloud:google-cloud-storage:1.2+'
  compile group: 'com.google.cloud', name: 'google-cloud-pubsub', version: '0.20+'
  compile ('com.google.cloud:google-cloud-datastore:1.2+')
  compile('com.google.apis:google-api-services-cloudkms:v1-rev15-1.22.0') {
     exclude(group: 'com.google.guava', module: 'guava-jdk5')
  }
  compile(group: 'com.google.api-client', name: 'google-api-client', version: '1.+') {
     exclude(group: 'com.google.guava', module: 'guava-jdk5')
  }
  compile(group: 'com.google.api-client', name: 'google-api-client-appengine', version: '1.+') {
     exclude(group: 'com.google.guava', module: 'guava-jdk5')
  }
}

The deployment environment is AppEngine standard java8.  I haven't been able to find the source code for ApiProxyImpl.java anywhere, so I'm unable to do much more debugging here.  I guess I'll try downgrading the dependency and hope it works.

After rolling back to the 0.11 dependencies I'm now getting an error about not being able to authenticate.  This may be due to differences between the flex and standard java8 environments because I never had this issue in the flex environment:
Caused by: java.util.concurrent.ExecutionException: io.grpc.StatusRuntimeException: UNAUTHENTICATED
	at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:500) ~[guava-20.0.jar:na]
	at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:401) ~[guava-20.0.jar:na]
	at com.google.api.gax.core.AbstractApiFuture.get(AbstractApiFuture.java:60) ~[gax-0.8.0.jar:na]
	at io.longreen.api.v1.service.ExecutionServiceImpl.createRunPolicyExecution(ExecutionServiceImpl.java:163) ~[classes/:na]
	... 84 common frames omitted
Caused by: io.grpc.StatusRuntimeException: UNAUTHENTICATED
	at io.grpc.Status.asRuntimeException(Status.java:545) ~[grpc-core-1.0.3.jar:1.0.3]
	at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:442) ~[grpc-stub-1.0.3.jar:1.0.3]
	at io.grpc.ClientInterceptors$CheckedForwardingClientCall.start(ClientInterceptors.java:203) ~[grpc-core-1.0.3.jar:1.0.3]
	at io.grpc.ForwardingClientCall.start(ForwardingClientCall.java:47) ~[grpc-core-1.0.3.jar:1.0.3]
	at com.google.api.gax.grpc.HeaderInterceptor$1.start(HeaderInterceptor.java:62) ~[gax-0.8.0.jar:na]
	at io.grpc.stub.ClientCalls.startCall(ClientCalls.java:273) ~[grpc-stub-1.0.3.jar:1.0.3]
	at io.grpc.stub.ClientCalls.asyncUnaryRequestCall(ClientCalls.java:252) ~[grpc-stub-1.0.3.jar:1.0.3]
	at io.grpc.stub.ClientCalls.futureUnaryCall(ClientCalls.java:189) ~[grpc-stub-1.0.3.jar:1.0.3]
	at com.google.pubsub.v1.PublisherGrpc$PublisherFutureStub.publish(PublisherGrpc.java:460) ~[grpc-google-cloud-pubsub-v1-0.1.6.jar:na]
	at com.google.cloud.pubsub.spi.v1.Publisher.publishOutstandingBatch(Publisher.java:333) ~[google-cloud-pubsub-0.11.2-alpha.jar:0.11.2-alpha]
	at com.google.cloud.pubsub.spi.v1.Publisher.publishAllOutstanding(Publisher.java:312) ~[google-cloud-pubsub-0.11.2-alpha.jar:0.11.2-alpha]
	at com.google.cloud.pubsub.spi.v1.Publisher.access$500(Publisher.java:76) ~[google-cloud-pubsub-0.11.2-alpha.jar:0.11.2-alpha]
	at com.google.cloud.pubsub.spi.v1.Publisher$5.run(Publisher.java:291) ~[google-cloud-pubsub-0.11.2-alpha.jar:0.11.2-alpha]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:295) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_112-google-v7]
	... 1 common frames omitted
Caused by: java.io.IOException: Could not get the access token.
	at com.google.auth.oauth2.AppEngineCredentials.refreshAccessToken(AppEngineCredentials.java:136) ~[google-auth-library-oauth2-http-0.6.0.jar:na]
	at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:149) ~[google-auth-library-oauth2-http-0.6.0.jar:na]
	at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:135) ~[google-auth-library-oauth2-http-0.6.0.jar:na]
	at io.grpc.auth.ClientAuthInterceptor.getRequestMetadata(ClientAuthInterceptor.java:150) ~[grpc-auth-1.0.3.jar:1.0.3]
	at io.grpc.auth.ClientAuthInterceptor.access$100(ClientAuthInterceptor.java:64) ~[grpc-auth-1.0.3.jar:1.0.3]
	at io.grpc.auth.ClientAuthInterceptor$1.checkedStart(ClientAuthInterceptor.java:96) ~[grpc-auth-1.0.3.jar:1.0.3]
	at io.grpc.ClientInterceptors$CheckedForwardingClientCall.start(ClientInterceptors.java:195) ~[grpc-core-1.0.3.jar:1.0.3]
	... 17 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.GeneratedMethodAccessor60.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112-google-v7]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112-google-v7]
	at com.google.auth.oauth2.AppEngineCredentials.refreshAccessToken(AppEngineCredentials.java:131) ~[google-auth-library-oauth2-http-0.6.0.jar:na]
	... 23 common frames omitted
Caused by: com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call memcache.Get in a thread that is neither the original request thread nor a thread created by ThreadManager
	at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:844) ~[runtime-shared.jar:na]
	at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:183) ~[runtime-shared.jar:na]
	at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:180) ~[runtime-shared.jar:na]
	at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:93) ~[appengine-api.jar:na]
	at com.google.appengine.api.memcache.MemcacheServiceImpl.quietGet(MemcacheServiceImpl.java:28) ~[appengine-api.jar:na]
	at com.google.appengine.api.memcache.MemcacheServiceImpl.get(MemcacheServiceImpl.java:51) ~[appengine-api.jar:na]
	at com.google.appengine.api.appidentity.AppIdentityServiceImpl.getAccessToken(AppIdentityServiceImpl.java:300) ~[appengine-api.jar:na]
	... 27 common frames omitted

In the end I wasn't able to find a workaround, so I had to revert all my recent changes.  In a separate test environment (Java 8 standard) I noticed a few other errors that may be relevant in addition to the original NullPointerException:
[s~mabl-prod-app/a2fd9e3b8f46288bf720544cdf894dac6fb55fbb.402925994294374259].<stdout>: [WARN] io.netty.util.NetUtil - Failed to find the loopback interface

[s~mabl-prod-app/a2fd9e3b8f46288bf720544cdf894dac6fb55fbb.402925994294374259].<stdout>: [WARN] io.netty.util.internal.MacAddressUtil - Failed to find a usable hardware address from the network interfaces; using random bytes: 4e:c1:f4:65:a3:40:fe:91

[s~mabl-prod-app/a2fd9e3b8f46288bf720544cdf894dac6fb55fbb.402925994294374259].<stdout>: [WARN] io.netty.util.NetUtil - Failed to retrieve the list of available network interfaces
java.net.SocketException: Inappropriate ioctl for device
	at java.net.NetworkInterface.getAll(Native Method) ~[na:1.8.0_112-google-v7]
	at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) ~[na:1.8.0_112-google-v7]
	at io.netty.util.NetUtil.<clinit>(NetUtil.java:171) ~[netty-common-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.util.internal.MacAddressUtil.bestAvailableMac(MacAddressUtil.java:50) [netty-common-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.util.internal.MacAddressUtil.defaultMachineId(MacAddressUtil.java:138) [netty-common-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.DefaultChannelId.<clinit>(DefaultChannelId.java:99) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.AbstractChannel.newId(AbstractChannel.java:107) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.AbstractChannel.<init>(AbstractChannel.java:79) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.nio.AbstractNioChannel.<init>(AbstractNioChannel.java:84) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.nio.AbstractNioByteChannel.<init>(AbstractNioByteChannel.java:55) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:98) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:88) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:81) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:74) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [na:1.8.0_112-google-v7]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) [na:1.8.0_112-google-v7]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [na:1.8.0_112-google-v7]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) [na:1.8.0_112-google-v7]
	at java.lang.Class.newInstance(Class.java:443) [na:1.8.0_112-google-v7]
	at io.netty.channel.ReflectiveChannelFactory.newChannel(ReflectiveChannelFactory.java:38) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:321) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.bootstrap.AbstractBootstrap.register(AbstractBootstrap.java:235) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.grpc.netty.NettyClientTransport.start(NettyClientTransport.java:215) [grpc-netty-1.4.0.jar:1.4.0]
	at io.grpc.internal.ForwardingConnectionClientTransport.start(ForwardingConnectionClientTransport.java:44) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.InternalSubchannel.startNewTransport(InternalSubchannel.java:217) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.InternalSubchannel.obtainActiveTransport(InternalSubchannel.java:190) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ManagedChannelImpl$SubchannelImplImpl.obtainActiveTransport(ManagedChannelImpl.java:827) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.GrpcUtil.getTransportFromPickResult(GrpcUtil.java:592) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.DelayedClientTransport.reprocess(DelayedClientTransport.java:295) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ManagedChannelImpl$LbHelperImpl$5.run(ManagedChannelImpl.java:733) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ChannelExecutor.drain(ChannelExecutor.java:87) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ManagedChannelImpl$LbHelperImpl.runSerialized(ManagedChannelImpl.java:724) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ManagedChannelImpl$NameResolverListenerImpl.onAddresses(ManagedChannelImpl.java:773) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.DnsNameResolver$1.run(DnsNameResolver.java:191) [grpc-core-1.4.0.jar:1.4.0]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_112-google-v7]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_112-google-v7]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_112-google-v7]

[s~mabl-prod-app/a2fd9e3b8f46288bf720544cdf894dac6fb55fbb.402925994294374259].<stdout>: [WARN] io.netty.util.internal.MacAddressUtil - Failed to retrieve the list of available network interfaces
java.net.SocketException: Inappropriate ioctl for device
	at java.net.NetworkInterface.getAll(Native Method) ~[na:1.8.0_112-google-v7]
	at java.net.NetworkInterface.getNetworkInterfaces(NetworkInterface.java:343) ~[na:1.8.0_112-google-v7]
	at io.netty.util.internal.MacAddressUtil.bestAvailableMac(MacAddressUtil.java:55) [netty-common-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.util.internal.MacAddressUtil.defaultMachineId(MacAddressUtil.java:138) [netty-common-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.DefaultChannelId.<clinit>(DefaultChannelId.java:99) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.AbstractChannel.newId(AbstractChannel.java:107) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.AbstractChannel.<init>(AbstractChannel.java:79) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.nio.AbstractNioChannel.<init>(AbstractNioChannel.java:84) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.nio.AbstractNioByteChannel.<init>(AbstractNioByteChannel.java:55) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:98) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:88) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:81) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:74) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [na:1.8.0_112-google-v7]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) [na:1.8.0_112-google-v7]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) [na:1.8.0_112-google-v7]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) [na:1.8.0_112-google-v7]
	at java.lang.Class.newInstance(Class.java:443) [na:1.8.0_112-google-v7]
	at io.netty.channel.ReflectiveChannelFactory.newChannel(ReflectiveChannelFactory.java:38) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:321) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.netty.bootstrap.AbstractBootstrap.register(AbstractBootstrap.java:235) [netty-transport-4.1.11.Final.jar:4.1.11.Final]
	at io.grpc.netty.NettyClientTransport.start(NettyClientTransport.java:215) [grpc-netty-1.4.0.jar:1.4.0]
	at io.grpc.internal.ForwardingConnectionClientTransport.start(ForwardingConnectionClientTransport.java:44) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.InternalSubchannel.startNewTransport(InternalSubchannel.java:217) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.InternalSubchannel.obtainActiveTransport(InternalSubchannel.java:190) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ManagedChannelImpl$SubchannelImplImpl.obtainActiveTransport(ManagedChannelImpl.java:827) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.GrpcUtil.getTransportFromPickResult(GrpcUtil.java:592) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.DelayedClientTransport.reprocess(DelayedClientTransport.java:295) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ManagedChannelImpl$LbHelperImpl$5.run(ManagedChannelImpl.java:733) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ChannelExecutor.drain(ChannelExecutor.java:87) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ManagedChannelImpl$LbHelperImpl.runSerialized(ManagedChannelImpl.java:724) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ManagedChannelImpl$NameResolverListenerImpl.onAddresses(ManagedChannelImpl.java:773) [grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.DnsNameResolver$1.run(DnsNameResolver.java:191) [grpc-core-1.4.0.jar:1.4.0]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_112-google-v7]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_112-google-v7]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_112-google-v7]

io.grpc.internal.ChannelExecutor drain: Runnable threw exception in ChannelExecutor (ChannelExecutor.java:89)
java.lang.NullPointerException
	at com.google.apphosting.runtime.ApiProxyImpl$CurrentRequestThreadFactory.newThread(ApiProxyImpl.java:1267)
	at com.google.common.util.concurrent.ThreadFactoryBuilder$1.newThread(ThreadFactoryBuilder.java:162)
	at java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:612)
	at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:925)
	at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1587)
	at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:336)
	at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:555)
	at io.grpc.internal.ManagedChannelImpl.rescheduleIdleTimer(ManagedChannelImpl.java:334)
	at io.grpc.internal.ManagedChannelImpl.access$700(ManagedChannelImpl.java:83)
	at io.grpc.internal.ManagedChannelImpl$2.handleNotInUse(ManagedChannelImpl.java:247)
	at io.grpc.internal.InUseStateAggregator.updateObjectInUse(InUseStateAggregator.java:60)
	at io.grpc.internal.ManagedChannelImpl$1.transportInUse(ManagedChannelImpl.java:198)
	at io.grpc.internal.DelayedClientTransport$2.run(DelayedClientTransport.java:116)
	at io.grpc.internal.ChannelExecutor.drain(ChannelExecutor.java:87)
	at io.grpc.internal.InternalSubchannel$TransportListener.transportReady(InternalSubchannel.java:458)
	at io.grpc.netty.ClientTransportLifecycleManager.notifyReady(ClientTransportLifecycleManager.java:58)
	at io.grpc.netty.NettyClientHandler$FrameListener.onSettingsRead(NettyClientHandler.java:646)
	at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder$FrameReadListener.onSettingsRead(DefaultHttp2ConnectionDecoder.java:412)
	at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder$PrefaceFrameListener.onSettingsRead(DefaultHttp2ConnectionDecoder.java:624)
	at io.netty.handler.codec.http2.Http2InboundFrameLogger$1.onSettingsRead(Http2InboundFrameLogger.java:93)
	at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readSettingsFrame(DefaultHttp2FrameReader.java:542)
	at io.netty.handler.codec.http2.DefaultHttp2FrameReader.processPayloadState(DefaultHttp2FrameReader.java:263)
	at io.netty.handler.codec.http2.DefaultHttp2FrameReader.readFrame(DefaultHttp2FrameReader.java:160)
	at io.netty.handler.codec.http2.Http2InboundFrameLogger.readFrame(Http2InboundFrameLogger.java:41)
	at io.netty.handler.codec.http2.DefaultHttp2ConnectionDecoder.decodeFrame(DefaultHttp2ConnectionDecoder.java:116)
	at io.netty.handler.codec.http2.Http2ConnectionHandler$FrameDecoder.decode(Http2ConnectionHandler.java:353)
	at io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:224)
	at io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:413)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1267)
	at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1078)
	at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
	at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:926)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:644)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:579)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:496)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:458)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
	at java.lang.Thread.run(Thread.java:745)

Also posted this to StackOverflow: https://stackoverflow.com/questions/45330377/pubsub-in-app-engine-standard-java-8-nullpointerexception-at-apiproxyimplcurre

Found a mention of a similar problem here:
https://groups.google.com/d/msg/google-appengine/2UTg4Eqskyk/PbqYEK3GAAAJ
I tried the work-around suggested there (https://gist.github.com/cmaan/7752e3c4fd0b1ba90a745cb6db232206)  and the NPE has stopped happening. But  now I'm back to the other UNAUTHENTICATED error:
Caused by: io.grpc.StatusRuntimeException: UNAUTHENTICATED
	at io.grpc.Status.asRuntimeException(Status.java:543) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:442) ~[grpc-stub-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:76) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:512) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$700(ClientCallImpl.java:429) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:544) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:52) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:117) ~[grpc-core-1.4.0.jar:1.4.0]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:295) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_112-google-v7]
	... 1 common frames omitted
Caused by: java.io.IOException: Could not get the access token.
	at com.google.auth.oauth2.AppEngineCredentials.refreshAccessToken(AppEngineCredentials.java:136) ~[google-auth-library-oauth2-http-0.7.0.jar:na]
	at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:149) ~[google-auth-library-oauth2-http-0.7.0.jar:na]
	at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:135) ~[google-auth-library-oauth2-http-0.7.0.jar:na]
	at io.grpc.auth.GoogleAuthLibraryCallCredentials$1.run(GoogleAuthLibraryCallCredentials.java:110) ~[grpc-auth-1.4.0.jar:1.4.0]
	... 7 common frames omitted
Caused by: java.lang.reflect.InvocationTargetException: null
	at sun.reflect.GeneratedMethodAccessor60.invoke(Unknown Source) ~[na:na]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112-google-v7]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112-google-v7]
	at com.google.auth.oauth2.AppEngineCredentials.refreshAccessToken(AppEngineCredentials.java:131) ~[google-auth-library-oauth2-http-0.7.0.jar:na]
	... 10 common frames omitted
Caused by: com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call memcache.Get in a thread that is neither the original request thread nor a thread created by ThreadManager
	at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:844) ~[runtime-shared.jar:na]
	at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:183) ~[runtime-shared.jar:na]
	at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:180) ~[runtime-shared.jar:na]
	at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:93) ~[appengine-api.jar:na]
	at com.google.appengine.api.memcache.MemcacheServiceImpl.quietGet(MemcacheServiceImpl.java:28) ~[appengine-api.jar:na]
	at com.google.appengine.api.memcache.MemcacheServiceImpl.get(MemcacheServiceImpl.java:51) ~[appengine-api.jar:na]
	at com.google.appengine.api.appidentity.AppIdentityServiceImpl.getAccessToken(AppIdentityServiceImpl.java:300) ~[appengine-api.jar:na]
	... 14 common frames omitted

I see you found my crazy workaround in https://gist.github.com/cmaan/7752e3c4fd0b1ba90a745cb6db232206
We stumbled upon the same UNAUTHENTICATED issues, as the automagic GAE authentication does not work anymore in a plain java thread pool. To deal with those you can use a PubSub client with explicit credentials, e.g.:
Publisher.defaultBuilder(topicName)
	.setCredentialsProvider(/* ... */)
	.build()

This way, we got Spanner and PubSub to work on java8.

Thanks for the tip, @cmaan.  I'm still having some trouble getting it working, though.  What credentials provider did you use?  Did you have to pass it in a file?
What I tried to do was to get the default credentials from AppEngine before applying the work-around, kind of like this:
static {
    defaultPubSubCredentials = TopicAdminSettings.defaultCredentialsProviderBuilder().build().getCredentials();
    GrpcUtilPatchThreadFactories.patch();
}

...
final Publisher publisher = Publisher.defaultBuilder(topicName)
    .setCredentialsProvider(new CredentialsProvider() {
        @Override
        public Credentials getCredentials() throws IOException {
            return ApiControllerFactory.defaultPubSubCredentials
                            .orElseThrow(() -> new InternalServiceException("No credentials defined"));
        }
    }).build();

That didn't seem to work, though.  I'm still getting the same UNAUTHENTICATED error with the message about not being able to call memcache.Get from that thread.
Maybe I'll have to put some service account credentials in a file in GCS and then load them in from there?

@garrettjonesgoogle @pongad Do you two see any reason why this might happen?

@jbaldassari One possible workaround is to use executor for Pub/Sub, as mentioned in #2150 . I think when gRPC request is initiated through executor (i.e., not in request thread), GrpcUtils will pick the right threadFactory. My guess is right now it picks requestThreadFactory, and new threads generated by this factory will be scoped to the request. So it will throw NPE.

@jbaldassari

Maybe I'll have to put some service account credentials in a file in GCS and then load them in from there?

There might be a better way, but that's exactly what we currently do

@neozwu I tried the workaround suggested in #2150, but I'm still getting the same NPE at ApiProxyImpl.java:1267.  Specifically I'm now doing this:
private static final ExecutorService executor =
    Executors.newCachedThreadPool(new ThreadFactoryBuilder()
        .setThreadFactory(Executors.defaultThreadFactory()).setDaemon(true)
            .setNameFormat("PubSubQueuePublisher-%d").build());
// ...
final PubsubMessage pubsubMessage = // ...
executor.submit(() -> publisher.publish(pubsubMessage)).get();

Am I supposed to be using a normal Java ExecutorService here, or is there some special way that I need to construct it?

Update on workaround testing:

Publish message only in thread created by normal Java Executorservice: NPE at ApiProxyImpl.java:1267
Create PubSubQueuePublisher and publish message inside thread created by ExecutorService: No NPE, but it still doesn't work because the AppEngine automatic authentication stuff doesn't work, and I just get an UNAUTHENTICATED error

I just tried another workaround which got me past both the ApiProxyImpl:1267 NPE and the UNAUTHENTICATED error, but now I'm stick again with a PERMISSION_DENIED error.  What I did was to first obtain App Engine credentials from within an AppEngine request thread, and then I passed those credentials into a ExecutorService thread to perform the actual RPC.  The trick was to force the credentials to be retrieved immediately in the request thread via a refresh() call.  Here's what the code looks like:
final Credentials pubSubCredentials = TopicAdminSettings.defaultCredentialsProviderBuilder().build().getCredentials();
pubSubCredentials.refresh();    // Force immediate retrieval of credentials from within request thread so that AppEngine automatic authentication works
executor.submit(() -> {
    final Publisher publisher = Publisher.defaultBuilder(topic)
         .setCredentialsProvider(FixedCredentialsProvider.create(pubSubCredentials))
         .build();
    try {
        return publisher.publish(pubsubMessage);
    } finally {
        publisher.shutdown();
    }
});

Unfortunately it fails when I retrieve the future result:
Caused by: java.util.concurrent.ExecutionException: io.grpc.StatusRuntimeException: PERMISSION_DENIED: User not authorized to perform this action.
	at com.google.common.util.concurrent.AbstractFuture.getDoneValue(AbstractFuture.java:500) ~[guava-20.0.jar:na]
	at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:377) ~[guava-20.0.jar:na]
	at com.google.api.core.AbstractApiFuture.get(AbstractApiFuture.java:62) ~[api-common-1.1.0.jar:na]
	at io.longreen.api.v1.service.ExecutionServiceImpl.createRunPolicyExecution(ExecutionServiceImpl.java:163) ~[classes/:na]
	... 76 common frames omitted
Caused by: io.grpc.StatusRuntimeException: PERMISSION_DENIED: User not authorized to perform this action.
	at io.grpc.Status.asRuntimeException(Status.java:543) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:442) ~[grpc-stub-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:76) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:512) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$700(ClientCallImpl.java:429) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:544) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:52) ~[grpc-core-1.4.0.jar:1.4.0]
	at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:117) ~[grpc-core-1.4.0.jar:1.4.0]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:295) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_112-google-v7]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_112-google-v7]
	... 1 common frames omitted

@neozwu please let me know if you can think of anything else to try.

@rrch per your https://github.com/GoogleCloudPlatform/google-cloud-java/issues/1752#issuecomment-292677737, is there any update on thread execution in GAE standard?

In grpc, it seems it returns currentRequestThreadFactory (link), which is from guava.  But maybe backendThreadFactory should be returned instead ?
/cc @ejona86 @ludoch

@neozwu It seems some shared grpc thread factories are actually decided by classloading side effects. I guess that's the reason why this demo [1] works on GAE j8, while almost every other realistic setup won't.
To replicate the classloading effect on static globals (similar to GrpcUtil.SHARED_CHANNEL_EXECUTOR), I've created a small toy project [2].
Regarding backgroundThreadFactory, this would make it impossible to use grpc with automatic scaling, right?
[1] https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/appengine-java8/spanner
[2] https://github.com/cmaan/threadfactory/

@cmaan thank you for your investigation, and your demo project. Let me summarize what I understand, and please feel free to correct me. So it seems
(1) when a Grpc call is initiated in an appengine request, the underlying grpc library will pick up currentRequestThreadFactory (by consulting the guava code) for its threading facilities, as demonstrated in your toy project.  This could potentially cause a problem.  Although I'm not exactly sure what the problem is. These Grpc threads created by currentRequestThreadFactory cannot outlive the request, but in #2150 sample code, the request thread is clearly blocked waiting for Grpc to complete.  Maybe appengine request thread times out ?
(2) But if the Grpc call is in a default background thread (by, for example, using executorService in appengine request), the underlying guava code will fail to invoke appengine api (even though the sys prop is set) due to appengine restrictions, and thus will use defaultThreadFactory, therefore Grpc will get defaultThreadFactory.
@jbaldassari would you mind sharing some sample code, to help further investigating this issue?

@neozwu sure, I can give you a couple of examples.  First, some context.  We have an interface called QueuePublisher with two implementations: InMemoryQueuePublisher and PubSubQueuePublisher.  For local testing we use InMemoryQueuePublisher which is backed by a simple Java blocking queue, and for deploying to AppEngine we use PubSubQueuePublisher.  The implementation is injected dynamically using Guice when the servlets are initialized.  So the PubSubQueuePublisher constructor is called at servlet initialization time via Guice, and the publish(QueueMessage method is called when servicing a request, presumably from an AppEngine request thread.
The following implementation does not work and results in NPE @ ApiProxyImpl.java:1267 : https://gist.github.com/jbaldassari/cf1160c7ef9207e6ddd562dc2a1951db
In the above example the PubSub Publisher is passed into the constructor, so it's being created initialized by Guice here.  I don't think that really matters because the problem seems to be related to fetching credentials the first time they are needed, but I thought I'd mention it anyway.
Here's another example that does not work, but for a different reason.  Here we're creating the Publisher in an ExecutorService thread.  In this case we get an UNAUTHENTICATED error when trying to retrieve the credentials, apparently because we're not in an AppEngine request thread: https://gist.github.com/jbaldassari/566f1f52e5406e72508c71fddfc515ef
Finally, a working example: https://gist.github.com/jbaldassari/3f9a93e8e956f16f5bad5d658d204e4c
Here we're retrieving the credentials from the AppEngine request thread but creating the Publisher and publishing the message from an ExecutorService thread.
Hopefully these examples help.  The key seems to be that in order for authentication to work the credentials must be retrieved from an AppEngine request thread, but in order to avoid the NPE the Publisher has to be created (or at least invoked?) from a normal Java thread.  If you need working and non-working examples with complete projects I can probably put something together this week, but it will take more time to create it and test it.

Take a look at https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/appengine-java8/gaeinfo (enable TOKEN) and you can get a token using the Metadata server from any thread.

https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/appengine-java8/gaeinfo/src/main/java/com/example/appengine/standard/GaeInfoServlet.java#L49-L58
and
https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/appengine-java8/gaeinfo/src/main/java/com/example/appengine/standard/GaeInfoServlet.java#L211-L218

In gRPC, IS_RESTRICTED_APPENGINE == false on GAE Java 8.

@ejona86 I'm not very familiar with gRPC codebase, but it seems to me regardless of IS_RESTRICTED_APPENGINE, the threadFactory will always be currentRequestThreadFactory when running in a request thread on GAE J7, or J8 .

@neozwu, ah, you're right. However, IS_RESTRICTED_APPENGINE other behavior. gRPC assumes it can have background threads when not restricted and so it shares threads across requests.

@ejona86 Yes, the restricted behavior for request threads makes sense. However, "AppEngine must immediately release shared resources, particularly executors which could retain request-scoped threads which become zombies after the request completes" applies to both GAE J7 and J8. Why IS_RESTRICTED_APPENGINE only checks for J7 ?

@neozwu, because GAE Java 8 didn't have that restriction. If it has that restriction, then at some point that changed. At the very least, we know it isn't as restricted as J7 because in J8 you can load binaries where in J7 you couldn't. Is there some documentation that describes the current limitations across all the GAE varieties?

@ejona86 :  confirmed with @ifigotin offline, on GAE J8, threads created by currentRequestThreadFactory still cannot outlive the request. This behavior is the same on J7 & J8.  So I think at least here the IS_RESTRICTED_APPENGINE part should apply to both J7 & J8 (not sure about other cases within grpc that rely on this flag).
/cc @ifigotin @ludoch @eamonnmcmanus

But if you create them as a normal java thread, they will. (at least on Java 8)

@lesv exactly, I think that's why using ExectuorService will work - a normal java thread cannot access appengine api, so the underlying guava code thinks it's not on appengine, and dispatches to gRPC a defaultThreadFactory, which creates threads that outlive request's lifecycle.

Why not use normal threads, and use the metadata server to get tokens?  The ExecutorService really looks bad and isn't easy.

@ejona86 , we need some kind of resolution for thread treatment by grpc in GAE J8.

Should work with latest pub sub library.
Reopen if you still see it with updated libs.


Resolve unresolved PDFObjectRefs

woops, apparently this was merged already, weird that it doesn't show up properly in the comparison


[Feature] Use dashboard to curb anxiety as case and casualty # grow

Is your feature request related to a problem? Please describe.
The dashboard is doing a really good job of providing a visual overview of the underlying data, but I am concerned that there is a lot of emphasis on how things are escalating (which is the honest truth and important to see).
I think people might increasingly be looking at the data for signs that lockdown and other measures are working and slowing spread down, but we know that this dashboard will debunk that idea over the next few weeks as more cases are detected due to spread (delayed because of incubation period) and increased testing capabilities, and as tally of casualties grow.
The dashboard may play a role in due time to help people comply with implemented measures to curb the spread of COVID or it may play a role in causing people to lose faith (based on data) in the implemented measures.
Describe the solution you'd like
Can we organise the dashboard to emphasise the positives a bit more? Recoveries, active cases vs closed cases, severe vs mild cases. (We mustn't let people lose hope as the pandemic numbers get worse).
Is it possible to add annotations such as when the state of disaster was implemented, lockdown started, other measures put in place (e.g. when the high-throughput testing equipment goes online) to explain some of the data we're seeing. Also to help people who may not be that familiar with this dataset and data in general to get context and adjust expectations?
Maybe show a shaded graph where we can show that we expect cases to grow drastically for the next few weeks at least before there could be a bit of a plateau.
Visualisations can drive anxiety (and the situation and data will cause anxiety regardless of how we visualise it), but I wonder if people have ideas to present the data as non-sensational but honestly as possible.
Additional context
The broader public may look at the data with different contexts than someone who knows the data. I've heard from a number of people that the red map from Harvard and seeing the numbers ticking over is creating massive anxiety for them.

Hey. Yes, will think about a couple of ways we can get this right.

Thanks! I'd be very happy to help brainstorm about how to do this or get data that can be added to annotate graphs. By no means my field of expertise, but let me know if I can help.

Useful post on the topic - more for mapping - https://www.esri.com/arcgis-blog/products/product/mapping/mapping-coronavirus-responsibly/

I think we can remove the table on the first page and move it to 2nd page and use that real estate to look and empowering people locally. So maybe notes on flattening the curvy through staying at home etc.


Add simple & demo example

Adds 2 more sets of example definitions.
Note that the updates for the target definition files already makes use of the authMode, so either this PR is merged after the next release or I update them "back" accordingly.

Looks good to me but can we please open another PR for the 0.9.0 branch also ?


iTerm support

Is it possible to open in iTerm.app instead of Terminal.app?

I also want to develop the kind Plug-in :)
Thank you.

I have created a separate project under the name "Open in iTerm" (https://github.com/sathya-me/Open-In-iTerm) to open the app in 'iTerm' and use terminal as backup and sent the pull request to 'alcatraz'. (https://github.com/supermarin/alcatraz-packages/pull/353). Hope it will be helpful once they accept it.
Thanks.


Feature request: Delete tags

UI: Next to "Save" button, add "Delete" button for all non-standard tags
Activity:
As a user, I click on the "Delete" button for a tag. I am prompted to confirm the deletion activity.
I expect the rooms under that tag to be moved to "Default", and the tag to be removed.

Or, you could just move everything into the room you want, and refresh (Ctrl+F5) the page, and the tag goes away.


[Relay] [Virtual Device] Store function result virtual device in virtual_device_ field

In this PR, I store the virtual device for a function result in the virtual_device_ field instead of in the function attributes. I am splitting this out from #9666 to isolate issues, and there will be a follow up PR moving the virtual devices of the function parameters into the virtual_device_ fields of the parameters themselves.

@mbs-octoml @mikepapadim @comaniac This is ready for review!

Note it's forked from #9690, which is forked from #9874, so until those go in those changes will be in the diff as well.

Looking through the change. Leaving some comments for your considerations(this is a bit subtle).
From a reader pov, a natural interpreation of value->virtual_device() is the device that the value will reside in during rumtime. Let us say fn is a function. A natural interpreation of fn->virtual_device()  could be the device that the function pointer(reference to the function) resides in. Note that is is not exactly the same interpretation as the device that the function's return value resides in, which is fn->body->virtual_device(), so it might be more consistent to use the later one.

@tqchen Thanks for the comment. You're right, it is a subtle difference that @mbs-octoml and I are very aware of. Currently, device planning assumes that 'stored on' is exactly the same as 'executes on'-- so fn->body->virtual_device() is always equivalent to fn->virtual_device(). This subtlety is documented here: https://github.com/apache/tvm/blob/main/src/relay/transforms/device_planner.cc#L180-L184
One downside (from an implementation standpoint) of storing the result virtual device on the function's body is that the body can be any type of Relay expression. Unfortunately, people reconstruct Relay exprs everywhere, willy-nilly. Virtual devices are not propagated through these constructors. This is why I implemented WithFields.
I haven't replaced all the constructors with WithFields, but I did just go through and replace all the Function constructors with WithFields so that this would work. If we did decide to switch to function->body->virtual_device(), we'd have to replace every Relay constructor with WithFields so that the virtual devices are properly propagated.
Since function->virtual_device() and function->body->virtual_device() are always going to be the same, and there's a significant engineering overhead for storing it on the body of the function, I'd prefer to keep it where it is. If you'd like to take on replacing all the Relay constructors with WithFields, then I'd be happy to make the change, just let me know.

Sorry, mistyped a bit above-- because the virtual device field doesn't store the virtual device for all expression types yet, func->body->virtual_device() will most likely be null in this implementation and therefore not be equivalent to func->virtual_device().
What will be true is that GetVirtualDevice(fn->body) is always equivalent to GetVirtualDevice(fn). (i.e., the 'conceptual' virtual device is the same even though it's not stored in the virtual device field of the body of the function).

Thanks @electriclilies  let me try to dissect what you said:

C0: Right now device propagation is not fully completed(through WithFields or other mechanisms), as a result funcion->body may not be property setup with the right device choice.
C1: There might be a need to properly annotate the return device type of function, which then can be used to inform, or enforce the planning of functions.

Note that C0 and C1 are slightly different. I believe you are talking about C0, but seems there is also a slightly indication of C1(which will imply storing something on the function node).
In a fully heterogenous setting, the input and return value might be different. In such cases, "execute on" can become ambiguous and differ from the "result of return value". The current change proposes to use fn->virtual_device() as the result of return value. It might be good to document this choice in function and revisit once device propagation is fully compeled.
These are high-level discussions for your information and hope that they will help clarifying the semantics of virtual device field. They are not asks about specific kind of implementation. So feel free to take the information and make a call, while documenting the rationales that might help future refactors.

Hi @tqchen, yes things do indeed get subtle on function types! I tried to capture that in the header mega-comment in device_planner.cc.
Inside the device planner we can talk about the 'device domain' for any expression, including those of function type which describes the device domains for the args and result separately. Ie the domain for planning is currently D := (D,...,D) -> D | VirtualDevice. And I declare (by fiat!) that the device holding the function or closure is the same as the device on which the function is executed which is the same as the device holding the functions result.
But when it comes time to the virtual_device field I'm not convinced it's worth exposing this higher-order domain machinery, so the field just has plain-old first order VirtualDevice.
So now we need a convention for what fn->virtual_device should be:
a. Leave it undefined -- you can't ask that question and must instead look at the virtual_device for the function param vars and the  body. I think that's your suggestion also.
b. Set it to be the function's result  device (and if the function returns a function it's the result device of that function, etc. This corresponds to the device planner's notion of 'result device'.) This was my suggestion to Lily, hence this PR.
c. Bite the bullet and store some new VirtualDeviceDomain on every expression instead of just VirtualDevice.
Wdyt?

Thanks @mbs-octoml . these are accurate summary of the state. I agree with you that it is not worth to go with c(high order machinary). Like I said I want to mainly clarifying the choices and and suggest documenting the semantics also in the IR data structure (assuming there will be alternative versions of device planner or consumers of the IR who will need to make use of such information, they will the read comments on the data structure for semantics).
From what I can see the current set of discussions are great and already comprehensive and I trust @electriclilies and you to make the call here.

Great, thanks. Ok my suggestion then is to stick with b) but beef up the comment
https://github.com/apache/tvm/blob/1ac01b4aa16b97db91b4254ae2ecdb15451c1d39/include/tvm/ir/expr.h#L179
to capture some of the 'hidden semantics' buried in the device planner commentary:
https://github.com/apache/tvm/blob/1ac01b4aa16b97db91b4254ae2ecdb15451c1d39/src/relay/transforms/device_planner.cc#L241).

Thanks @electriclilies @mbs-octoml

@mbs-octoml OK, so I ended up changing the parser to parse the virtual device in for the tests. I'm not married to the syntax-- right now I'm just putting the virtual device right after the return type of the function, separated by a comma.  I'm thinking this will generalize well to parameter types.
So for now it''s like this:
fn main(%x: Tensor([1, 2, 3])) -> Tensor([1, 2, 3, 4]), virtual_device:meta[VirtualDevice][1] { body }
One thing I wasn't sure about was the approach for keywords in the parser-- I couldn't find where the keywords are checked, so I just am letting virtual_device be any identifier for now. @jroesch any insight on this?

I realized that the representation of the program after device planning needs some more thought, and this influences how the device planned program is represented in relay script. Pausing work on this PR till I have done a more detailed design review.

I ended up just lifting the result virtual device out of the attributes, will discuss dealing with the on_device ops in a later PR.


Introduce events with phases to replace multiple events required to perform a single operation

Thanks to today's call with @ikbalkaya I've come up with an idea of events with phases (or stages, steps, the name is yet to be defined).
Background
At the core of our SDKs we have a sequential events queue. It allows us to safely access and mutate the state in a multi-threaded world such as the Android one. The key concept of the queue is: you can only access and mutate the state from the events queue thread. This creates some challenges when it comes to async code. For some operations (like adding a trackable) we need to run async code and wait for the result. We could do this in a blocking manner but then the whole queue would have to stop and the whole SDK will wait for that async callback result. This is something we don't want to happen so instead, we are launching this async code and continuing other events processing. When the callback is ready then we simply create another event and put it in the queue to continue the operation.
Problem
Because of the way of handling async code we have to define multiple events for a single operation. Those events then are scattered in the class and it's hard to get a view of the whole operation. Additionally, there are multiple places at which you should look when making a change, so it's very easy to miss something and introduce a bug. For example, the add() operation uses 4 events: AddTrackableEvent, AddTrackableFailedEvent, ConnectionForTrackableCreatedEvent, ConnectionForTrackableReadyEvent.
Solution
To keep the whole operation code in the same place and still be able to gracefully handle async code we can introduce a new field to the events. This field could be called a phase or state or step but I'll stick to the phase for now. This field would probably be an enum and will indicate in which phase of the operation we are right now. Then all we need is a when (event.phase) {...} block and we could put the appropriate code in the correct phases. Thanks to that, instead of creating new events each time some async code has returned with a result, we would simply re-use the same event that started the whole operation, but we will override its phase field. Please look at the code example below to see the benefits of this approach.
Code examples
How it looks like right now:
for (event in eventsQueue) {
  when (event) {

    // --------------------------------------------
    // some other events handling code
    // --------------------------------------------

    is AddTrackableEvent -> {
      // do some processing and state mutation
      launchSomeAsyncWork() { asyncResult ->
        if (asyncResult.success)
          eventsQueue.put(ConnectionForTrackableCreatedEvent())
        else
          eventsQueue.put(AddTrackableFailedEvent())
      }
    }

    // --------------------------------------------
    // some other events handling code
    // --------------------------------------------

    is AddTrackableFailedEvent -> {
      // handle failed state and return failure
    }

    // --------------------------------------------
    // some other events handling code
    // --------------------------------------------

    is ConnectionForTrackableReadyEvent -> {
      // mutate state and return success
    }

    // --------------------------------------------
    // some other events handling code
    // --------------------------------------------

    is ConnectionForTrackableCreatedEvent -> {
      // do some processing and state mutation
      launchSomeAsyncWork() { asyncResult ->
        if (asyncResult.success)
          eventsQueue.put(ConnectionForTrackableReadyEvent())
        else
          eventsQueue.put(AddTrackableFailedEvent())
      }
    }

    // --------------------------------------------
    // some other events handling code
    // --------------------------------------------

  }
}

How it will look after the refactor:
for (event in eventsQueue) {
  when (event) {

    // --------------------------------------------
    // some other events handling code
    // --------------------------------------------

    is AddTrackableEvent -> {
      when (event.phase) {
        AddTrackablePhase.START - > {
          // do some processing and state mutation
          launchSomeAsyncWork() { asyncResult ->
            if (asyncResult.success)
              eventsQueue.put(event.copy(phase = CONNECTION_CREATED))
            else
              eventsQueue.put(event.copy(phase = FAILED))
          }
        }
        AddTrackablePhase.CONNECTION_CREATED - > {
          // do some processing and state mutation
          launchSomeAsyncWork() { asyncResult ->
            if (asyncResult.success)
              eventsQueue.put(event.copy(phase = CONNECTION_READY))
            else
              eventsQueue.put(event.copy(phase = FAILED))
          }
        }
        AddTrackablePhase.CONNECTION_READY - > {
          // mutate state and return success
        }
        AddTrackablePhase.FAILED - > {
          // handle failed state and return failure
        }
      }
    }

    // --------------------------------------------
    // some other events handling code
    // --------------------------------------------

  }
}

┆Issue is synchronized with this Jira Task by Unito

After the event queue refactoring this is not relevant anymore


Add qasim_khan.jpg rising temperature file

I have added a plot that visualizes the effect of climate change on the mean annual temperature in the US. I created this during a programming course.

Thanks @QasimKhan5x for your interests and contributions :)


Installation page does not discuss how to set-up a private gitlab repo with SSh key

Are you referring to https://fluxcd.io/docs/installation/#gitlab-and-gitlab-enterprise?

Have you seen https://fluxcd.io/docs/cmd/flux_bootstrap_gitlab/ as well? Maybe we should link to it from that section to cover additional use-cases..?

Hello Daniel,
Yes indeed i am referring to the section at : https://fluxcd.io/docs/installation/#gitlab-and-gitlab-enterprise.
I haven't seen the CLI reference page but this one doesn't hint me in the correct direction it seems.
I very naively ran
flux bootstrap gitlab --ssh-hostname=<gitlab-hostname> --hostname=<gitlab-hostname> --token-auth  --owner=<owner group> --repository=flux --branch=master --path=clusters/dev-ocp4
Which created the following yaml manifest in the target repository:
# This manifest was generated by flux. DO NOT EDIT.
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 1m0s
  ref:
    branch: master
  secretRef:
    name: flux-system
  url: https://<gitlab-hostname>/<owner-group>/flux.git
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 10m0s
  path: ./clusters/dev-ocp4
  prune: true
  sourceRef:
    kind: GitRepository
    name: flux-system

I also found this page https://fluxcd.io/docs/components/source/gitrepositories/#ssh-authentication. I edited the gitrepository object on OCP side to mention a "ssh url" and created the appropriate secrets , but as i am new to flux, I am not sure that this is the correct way to go (and flux is still not reconciliated with the repo anyway )


mavproxy: 1.8.29 -> 1.8.30

Automatic update generated by nixpkgs-update tools. This update was made based on information from passthru.updateScript.
meta.description for mavproxy is: "MAVLink proxy and command line ground station"
meta.homepage for mavproxy is: "https://github.com/ArduPilot/MAVProxy"
meta.changelog for mavproxy is: ""
Updates performed

Ran passthru.UpdateScript

To inspect upstream changes
Impact

Checks done (click to expand)

built on NixOS

The tests defined in passthru.tests, if any, passed

0 of 0 passed binary check by having a zero exit code.

0 of 0 passed binary check by having the new version present in output.

found 1.8.30 with grep in /nix/store/7ygh7491pasfiy0wziahzwvp23fix5dw-MAVProxy-1.8.30

directory tree listing: https://gist.github.com/5c727e30b50bfe89dc65785d335dfbb3

du listing: https://gist.github.com/73a1f282d78df74027fd733e5d577f1e

Rebuild report (if merged into master) (click to expand)

4 total rebuild path(s)

1 package rebuild(s)

1 x86_64-linux rebuild(s)
1 i686-linux rebuild(s)
1 x86_64-darwin rebuild(s)
1 aarch64-linux rebuild(s)

First fifty rebuilds by attrpath
mavproxy

Instructions to test this update (click to expand)

Either download from Cachix:
nix-store -r /nix/store/7ygh7491pasfiy0wziahzwvp23fix5dw-MAVProxy-1.8.30 \
  --option binary-caches 'https://cache.nixos.org/ https://nix-community.cachix.org/' \
  --option trusted-public-keys '
  nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
  cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
  '

(The Cachix cache is only trusted for this store-path realization.)
For the Cachix download to work, your user must be in the trusted-users list or you can use sudo since root is effectively trusted.
Or, build yourself:
nix-build -A mavproxy https://github.com/r-ryantm/nixpkgs/archive/36741094cec10a3facf318fc1bce97efc92da881.tar.gz

After you've downloaded or built it, look at the files and if there are any, run the binaries:
ls -la /nix/store/7ygh7491pasfiy0wziahzwvp23fix5dw-MAVProxy-1.8.30
ls -la /nix/store/7ygh7491pasfiy0wziahzwvp23fix5dw-MAVProxy-1.8.30/bin

Pre-merge build results
We have automatically built all packages that will get rebuilt due to
this change.
This gives evidence on whether the upgrade will break dependent packages.
Note sometimes packages show up as failed to build independent of the
change, simply because they are already broken on the target branch.
Result of nixpkgs-review run on x86_64-linux 1

1 package built:

mavproxy

Maintainer pings
cc @lopsided98 for testing.

@ofborg build mavproxy

@ofborg test mavproxy

Result of nixpkgs-review pr 107485 run on x86_64-darwin 1

1 package marked as broken and skipped:

mavproxy


Tooltip style cannot be set in NEllipsis

TuSimple/naive-ui version (版本)
2.34.4
Vue version (Vue 版本)
3.3.4
Browser and its version (浏览器及其版本)
Chrome 113.0.5672.126 (arm64)（macos）
System and its version (系统及其版本)
macos(13.3.1)
Node version (Node 版本)
v18.16.0
Reappearance link (重现链接)
https://codesandbox.io/s/unruffled-hellman-27krj1?file=/src/Demo.vue
Reappearance steps (重现步骤)
I want to set tooltip width, because tooltip maxWidth was deprecated.
Expected results (期望的结果)
use tooltip style can be set normally.
Actual results (实际的结果)
it can't, and type was incorrect.
Remarks (补充说明)

Try using this prop:

Try using this prop:

Thank you very much for your answer! Yes, it will work, but it will display extra length in the content very short time

Give me a repo, I'll investigate it

Give me a repo, I'll investigate it

Thanks!!!, Repo was here: https://github.com/artsmp0/gupo-naive-admin/blob/master/src/layout/components/Sider.vue#L44

This issue does not have any recent activity. If you are still experiencing similar problems, open a new error, including a minimal copy of the problem


How to query for a single component given an entity?

Hello
Inside a view, i want to check if an entity has a specific component, and if he does query it
I could create a single view and then check for the entity id, but that seems overkill when i just want to check if it has a flag and query its value
Thanks!

Hello, you can use:
/*
    Returns the pointer to the given component type data for the entity
    or nullptr if the entity doesn't have this component.
    Warning: Using an invalid entity results in undefined behavior.
    Note: This is safer but slower than de_get.
*/
void* de_try_get(de_ecs* r, de_entity e, de_cp_type cp_type);

Views are for iteration, if you just want to check for a specific component in a specific entity just use that function.

Awesome thanks a lot!


feat(tree): Return block status for old blocks

Did some refactoring but main change is that for old blocks we are checking if they are part of canonical chain that is in database and returning BlockStatus::Valid if that is the case.
closes: https://github.com/paradigmxyz/reth/issues/2437

🤖 Generated by Copilot at ed78d8f
Summary
🌲🕵🧪

This pull request adds a new function to check block status and refactors the block insertion logic in the blockchain-tree crate. It also updates the ShareableBlockchainTree struct to use the new functions and simplify the code.

Sing, O Muse, of the cunning code that the heroes wrought
To explore the branching paths of the blockchain tree
And to discern the known from the unknown blocks
With a swift and simple function, is_block_known.

Walkthrough

Rename and refactor block insertion functions in blockchain_tree.rs (link, link, link, link, link, link, link, link, link, link, link, link)
Add BlockIdProvider trait to the imports in blockchain_tree.rs (link)
Replace ensure_block_is_in_range function with is_block_known function in blockchain_tree.rs (link)
Change log level for the message indicating that the block is already canonical in blockchain_tree.rs (link)

Codecov Report

Merging #2462 (554f95e) into main (435df44) will decrease coverage by 24.55%.
The diff coverage is 41.09%.

:mega: This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more
@@             Coverage Diff             @@
##             main    #2462       +/-   ##
===========================================
- Coverage   70.54%   45.99%   -24.55%
===========================================
  Files         487      487
  Lines       60503    60545       +42
===========================================
- Hits        42681    27848    -14833
- Misses      17822    32697    +14875

Flag
Coverage Δ

integration-tests
18.10% <0.00%> (+2.01%)
:arrow_up:

unit-tests
39.34% <41.09%> (-27.29%)
:arrow_down:

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files
Coverage Δ

crates/blockchain-tree/src/blockchain_tree.rs
20.52% <39.70%> (-68.23%)
:arrow_down:

crates/blockchain-tree/src/shareable.rs
36.48% <60.00%> (+0.37%)
:arrow_up:

... and 244 files with indirect coverage changes


Gram Equivalents Calculator

Enter calculator name -
Gram Equivalents Calculator
Describe calculator functionality -
The Gram Equivalents Calculator takes the weight and Equivalent weight of the solute and calculates the gram equivalents of it.
The inputs and outputs are inter-connected, if the user tries to change one of them, the other two values maintain the correct dependency and change along with it.
Under which category you wish to place it -

[ ] Computer Science
[ ] Mathematics
[ ] Physics
[x] Chemistry
[ ] Biology
[ ] Art
[ ] Finance
[ ] Scientific
[ ] Health
[ ] Sports
[x] Let project owner decide
[ ] Suggest a new category - (Answer here)

@syash7202,
Abiding by the contribution policy, not more than 2 issues can be assigned at a time.
Kindly comment once the previous issues are merged.


{VM} Fix extension image list-versions example

{VM} Fix extension image list-versions example
Related command
az vm extension image list-versions
Description
Update example of az vm extension image list-versions
Fixes GitHub issue 24943
Testing Guide

History Notes

[Component Name 1] BREAKING CHANGE: az command a: Make some customer-facing breaking change
[Component Name 2] az command b: Add some customer-facing feature

This checklist is used to make sure that common guidelines for a pull request are followed.

[x] The PR title and description has followed the guideline in Submitting Pull Requests.

[x] I adhere to the Command Guidelines.

[x] I adhere to the Error Handling Guidelines.

VM


Demo hint on resend verification email page

The demo user hint box is visible on the verification email resend page. The information is irrelevant on that page and should be removed.

See: https://github.com/meteor-useraccounts/core/blob/master/Guide.md
I think the reactive AccountsTemplates.getState() === 'signIn' will help here.
Let me give it a shot!


Failed to get request token in android and ios.

Hello Team
i am facing a issue with this library ( "Failed to get request token" ) Android, IOS  both platform.
I also try it with in a fresh project and followed the Twitter app setup process or i got the consumer and secret key's.
But  when i requesting with this credentials it is returning the error ("Failed to get request token") some time before it was working in other project but after install the node modules it stopped working.

I did some search about this issue and most of developers and referencing to to check your callBack url's on your Twitter
developer app, ( so i remove the previous callbacks and add them again )  but it is still retiring same error.

After more analysis i found the twitter api's and i try with these api.

1. Get request token api ( Add your consumer key )
let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.twitter.com/oauth/request_token?oauth_consumer_key=YOUR_CONSUMER_KEY&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1698819571&oauth_nonce=aPINykwfTb5&oauth_version=1.0&oauth_signature=y7282t0yKdERK%2FgknyH335z1LM4%3D',
  headers: {
    'Cookie': 'guest_id=v1%3A169875337548246364; guest_id_ads=v1%3A169875337548246364; guest_id_marketing=v1%3A169875337548246364; personalization_id="v1_sqUWzpLK9KbN3iJS3AwtqA=="'
  }
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

2. After run this api it will return a string, we will pass this string in next api.
We need to prepare the url like below.
https://api.twitter.com/oauth/authorize?ADD_YOUR_STRING_FROM_FROM_API_RESPONSE
Then hit this URL in your browser so this will redirect you on app authorization page.
Now i think my Twitter app and its callbacks setup is right.
I checked the Logcat in android studio and here is the my  issue.

I saw the code inside the OAuthController file
Inside this startAuth function is calling ( oAuth1aService.requestTempToken)
I think (oAuth1aService.requestTempToken) is throwing Error  so inside the newRequestTempTokenCallback function failure function is calling, and  it is returning a error message (Failed to get request token)
It is the error response in my node server
{"nativeStackAndroid":[{"lineNumber":94,"file":"OAuthController.java","methodName":"failure","class":"com.twitter.sdk.android.core.identity.OAuthController$1"},{"lineNumber":191,"file":"OAuth1aService.java","methodName":"failure","class":"com.twitter.sdk.android.core.internal.oauth.OAuth1aService$1"},{"lineNumber":48,"file":"Callback.java","methodName":"onFailure","class":"com.twitter.sdk.android.core.Callback"},{"lineNumber":92,"file":"DefaultCallAdapterFactory.java","methodName":"run","class":"retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$2"},{"lineNumber":942,"file":"Handler.java","methodName":"handleCallback","class":"android.os.Handler"},{"lineNumber":99,"file":"Handler.java","methodName":"dispatchMessage","class":"android.os.Handler"},{"lineNumber":201,"file":"Looper.java","methodName":"loopOnce","class":"android.os.Looper"},{"lineNumber":288,"file":"Looper.java","methodName":"loop","class":"android.os.Looper"},{"lineNumber":7872,"file":"ActivityThread.java","methodName":"main","class":"android.app.ActivityThread"},{"lineNumber":-2,"file":"Method.java","methodName":"invoke","class":"java.lang.reflect.Method"},{"lineNumber":548,"file":"RuntimeInit.java","methodName":"run","class":"com.android.internal.os.RuntimeInit$MethodAndArgsCaller"},{"lineNumber":936,"file":"ZygoteInit.java","methodName":"main","class":"com.android.internal.os.ZygoteInit"}],"userInfo":null,"message":"Failed to get request token","code":"USER_CANCELLED"}
Please help me to fix my issue because it's urgent.
Thank you.

Check this post Sign in with Twitter users must whitelist callback URLs
https://twittercommunity.com/t/action-required-sign-in-with-twitter-users-must-whitelist-callback-urls/105342
https://github.com/parse-community/Parse-SDK-iOS-OSX/issues/1310#issuecomment-397343370
and may be this will help you try to change callback url
https://stackoverflow.com/questions/33228235/failed-to-get-request-token-on-android-m-running-devices

Facing a same issue, @kamalkishor8878 Did you find a any solution ?

No i didn't found the solutions.
I have tried these lib.
npm i @hackinggate/react-native-twitter-signin npm i react-native-login-twitter npm i react-native-twitter-auth  npm i @cutii/react-native-twitter-signin v0.0.4 npm i react-native-twitter ( did not try on it because last version released was 6 year ago)
Most of these library is frocked from
npm i GoldenOwlAsia-react-native-twitter-signin
And i have  also tried with diffrent sdk versions.
com.twitter.sdk.android:twitter-core:3.0.0 com.twitter.sdk.android:twitter-core:3.1.0 com.twitter.sdk.android:twitter-core:3.1.1 com.twitter.sdk.android:twitter-core:3.2.0 com.twitter.sdk.android:twitter-core:3.3.0
Now i am trying to do with the twitter api's
https://api.twitter.com/oauth/request_token https://api.twitter.com/oauth/authorize
But unable to get the authorised user detail.

Check this post Sign in with Twitter users must whitelist callback URLs https://twittercommunity.com/t/action-required-sign-in-with-twitter-users-must-whitelist-callback-urls/105342
parse-community/Parse-SDK-iOS-OSX#1310 (comment)
and may be this will help you try to change callback url https://stackoverflow.com/questions/33228235/failed-to-get-request-token-on-android-m-running-devices

Thanks for sharing these link's, I have checked these link and didn't get the solution.

No i didn't found the solution.
I have tried another twitter lib.
npm i @hackinggate/react-native-twitter-signin npm i react-native-login-twitter npm i react-native-twitter-auth npm i @cutii/react-native-twitter-signin v0.0.4 npm i react-native-twitter ( did not try on it because last version released was 6 year ago)  Most of these library is frocked from npm i GoldenOwlAsia-react-native-twitter-signin And i have also tried with diffrent sdk versions.
com.twitter.sdk.android:twitter-core:3.0.0 com.twitter.sdk.android:twitter-core:3.1.0 com.twitter.sdk.android:twitter-core:3.1.1 com.twitter.sdk.android:twitter-core:3.2.0 com.twitter.sdk.android:twitter-core:3.3.0  Now i am trying to do with the twitter api's
https://api.twitter.com/oauth/request_token https://api.twitter.com/oauth/authorize But unable to get the authorised user detail.

Thank you for your reply, I think twitter change their api and not old version of react-native-twitter-signin library is not supporting latest with latest twitter api

any update on this?

Any update?

Still searching about it in free time,  developer is facing the same issue.
I don't fount any update.
https://twittercommunity.com/t/can-not-login-sign-in-to-twitter-from-react-native-application/208346


Added google sign in

Fixes #15
Added Google SignIn and removed "null" in AppBar and replaced it with User name
Video :
https://user-images.githubusercontent.com/96647299/218199522-b6bc720a-a339-417c-b12d-b0d1ff13b178.mp4

Hi @Perumallpardhiv,
Thanks for creating the PR.
This functionality is already available and is commented on for the time being.  Refer #1


Handling of isort-related errors and other autofix codes

With #25 being merged soon, the question remains whether formatting should be enabled by default and error codes should be given to be auto-fixed when running formatting.
I don't really mind on or the other, so I'm open to suggestions.
If e.g. isort-codes should be used for formatting per default, we should also disable pylsp-isort.

i am curious to ask if this can offer 'additionalTextEdits' which offer auto-fix for auto-import when writing a method but did not import it yet.

That depends on whether ruff supports this kind of action. I couldn't find any immediate support for that, but as far as I know rope (and thus pylsp-rope) supports this.

ohh, wish ruff supported it asap.
// pylsp-rope seems a bit buggy, and wish ruff was the only one enhancement dependency of pylsp.
shane.xb.qian

You could create a feature request issue on ruff's github but i think the idea of ruff is to stay on providing linting features rather than code reformat actions. Nevertheless it might be worth the try.


Feature Request - Post Install

It would be great to be able to have the post install feature in desired state. Currently using the dirty DSC script resource below to do the job.
Script WSUSPostInstall
{
    DependsOn = '[File]WSUSContentDirectory'
    GetScript = {
        @{
            GetScript = $GetScript
            SetScript = $SetScript
            TestScript = $TestScript
            Result = ($null -ne (Get-Website -Name 'WSUS Administration') -and (Test-Path -Path "$($Using:Node.ServicesVolume)\WSUS\WsusContent\anonymousCheckFile.txt"))
        }
    }

    SetScript = {
        & 'C:\Program Files\Update Services\Tools\WsusUtil.exe' postinstall CONTENT_DIR=$($Using:Node.ServicesVolume)\WSUS
    }

    TestScript = {
        $Status = ($null -ne (Get-Website -Name 'WSUS Administration') -and (Test-Path -Path "$($Using:Node.ServicesVolume)\WSUS\WsusContent\anonymousCheckFile.txt"))
        $Status -eq $True
    }
}

Sorry ignore this one. The resource already handles post install.


Feature request: have a flag to open a specific remote with repo command

It would be great if you could use a command like git repo [remotename] to open a specific remote repo (not just origin).

That's a great idea!


Uploading file with Alpakka AWS S3 connector

I am adding an upload function to my Play Framework app.
def saveS3FileService(filename: String, tempFile: java.nio.file.Path): Future[MultipartUploadResult] = {
    val s3Sink: Sink[ByteString, Future[MultipartUploadResult]] = S3.multipartUpload(s3fsBucket, filename)
    FileIO.fromPath(tempFile).runWith(s3Sink)
}

And I got the following exception reported:
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[S3Exception: {"error":"volume id some-file.bmp not found: Unknown volume id some-file.bmp"}]]
It seems I can only use a File ID rather than a file name here. Besides, when I try to list the content in the bucket with the following code.
def listS3Files(): Future[Seq[String]] = {
    S3.listBucket(s3fsBucket, None)
        .map(c => c.toString)
        .runWith(Sink.seq[String])
  }

The following exception is encounter. I think Alpakka was expecting some XML response from S3, rather than HTML.
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[UnsupportedContentTypeException: Unsupported Content-Type [Some(text/html; charset=UTF-8)], supported: application/xml; charset=UTF-8]]
I have no experience with AWS S3 and I have not test my code on real S3 and therefore, I cannot comment whether it is Alpakka or Seaweed problem.

Need to have a way to reproduce it.
I have no experience with Alpakka.

Seems you configured s3 endpoint wrong. It should not point to the master. It should point to s3 gateway.
Usually the S3 end point is http://localhost:8333

You are right. I pointed to localhost:9333. However, I encountered another exception after setting the end point to localhost:8333.
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[S3Exception: ]]
	at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:359)
	at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:261)
	at play.filters.cors.AbstractCORSPolicy$$anonfun$1.applyOrElse(AbstractCORSPolicy.scala:128)
	at play.filters.cors.AbstractCORSPolicy$$anonfun$1.applyOrElse(AbstractCORSPolicy.scala:126)
	at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:417)
	at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:41)
	at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
	at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:70)
	at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:72)
	at scala.concurrent.impl.Promise$DefaultPromise.$anonfun$tryComplete$1(Promise.scala:288)
Caused by: akka.stream.alpakka.s3.S3Exception:
	at akka.stream.alpakka.s3.S3Exception$.apply(S3Exception.scala:73)
	at akka.stream.alpakka.s3.impl.S3Stream$.$anonfun$unmarshalError$1(S3Stream.scala:246)
	at scala.util.Success.$anonfun$map$1(Try.scala:255)
	at scala.util.Success.map(Try.scala:213)
	at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
	at akka.http.scaladsl.util.FastFuture$FulfilledFuture.transform(FastFuture.scala:84)
	at scala.concurrent.Future.map(Future.scala:292)
	at scala.concurrent.Future.map$(Future.scala:292)
	at akka.http.scaladsl.util.FastFuture$FulfilledFuture.map(FastFuture.scala:77)

In additions, I have added a file with AWS CLI and Alpakka listBucket returned nothing. I wonder this could be some other configuration problems. Do you have any idea? The following is the configuration I am using. Thanks!
alpakka.s3 {
  # whether the buffer request chunks (up to 5MB each) to "memory" or "disk"
  buffer = "memory"

  # location for temporary files, if buffer is set to "disk". If empty, uses the standard java temp path.
  disk-buffer-path = ""

  # DEPRECATED since Alpakka 1.0.1
  # Please use alpakka.s3.endpoint-url for setting custom scheme, host and port.
  proxy {
    # hostname of the proxy. If undefined ("") proxy is not enabled.
    host = ""
    # port = 8000

    # if "secure" is set to "true" then HTTPS will be used for all requests to S3, otherwise HTTP will be used
    secure = false
  }

  # An address of a proxy that will be used for all connections using HTTP CONNECT tunnel.
  # forward-proxy {
  #   scheme = "https"
  #   host = "proxy"
  #   port = 8080
  #   credentials {
  #     username = "username"
  #     password = "password"
  #   }
  # }

  # default values for AWS configuration
  aws {
    # If this section is absent, the fallback behavior is
    # to use the same configuration as if credentials.provider = default
    credentials {
      # anonymous requests (no auth)
      #
      # provider = anon

      # static credentials
      #
      # provider = static
      # access-key-id = ""
      # secret-access-key = ""
      # token = "" # optional

      # default: as described in software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider docs,
      # attempts to get the credentials from either:
      #   - environment variables
      #   - system properties
      #   - credentials file
      #   - EC2 credentials service
      #   - IAM / metadata
      provider = static
      access-key-id = "any"
      secret-access-key = "any"

    }

    # If this section is absent, the fallback behavior is
    # to use the same configuration as if region.provider = default
    region {
      # static credentials
      #
      # provider = static
      #
      # This can be set to the `id` value of any of the regions defined in
      # software.amazon.awssdk.regions.Region
      # default-region = ""

      # default: as described in software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain docs,
      # attempts to get the region from either:
      #   - environment variables
      #   - system properties
      #   - progile file
      #   - EC2 metadata
      provider = static
      default-region = "us-east-1"
    }
  }

  # DEPRECATED (since Alpakka 2.0.0)
  # AWS S3 is going to retire path-style access, thus prefer the virtual-host-style access
  # https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/
  #
  # Also, prefer to use the newer access-style property.
  #
  # Possible values:
  #  - false: use virtual-host style access
  #  - true: use legacy path-style access, warnings will be logged
  #  - force: use legacy path-style access, disable warnings
  #  - empty, null or absent (default): use `access-style`, which in turn defaults to virtual-host style access
  # path-style-access = false

  # Which access style to use. Prefer to use this setting over path-style-access.
  # Path-style access has been deprecated by Amazon and will not work on buckets created after September 30, 2020.
  # For alternative S3 implementations (MinIO, Rados Gateway, etc.), path-style access may continue to be required.
  # Possible values:
  #  - virtual: virtual host-style access, i.e. https://<bucket name>.s3.amazonaws.com/file/inside/bucket
  #  - path: path-style access, i.e. https://<region>.amazonaws.com/<bucket>/file/inside/bucket
  access-style = virtual

  # Custom endpoint url, used for alternate s3 implementations
  # To enable virtual-host-style access with Alpakka S3 use the placeholder `{bucket}` in the URL
  # eg. endpoint-url = "http://{bucket}.s3minio.alpakka:9000"
  #
  endpoint-url = "http://<IP_ADDRESS>:8333"

  # Which version of the list bucket api to use. Set to 1 to use the old style version 1 API.
  # By default the newer version 2 api is used.
  list-bucket-api-version = 2

  # Object keys are validated to NOT use sub-directory selection with `..` to improve security.
  # This flag may disable the validation.
  # See https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
  validate-object-key = true

  # Default settings corresponding to automatic retry of requests in an S3 stream.
  retry-settings {
    # The maximum number of additional attempts (following transient errors) that will be made to process a given
    # request before giving up.
    max-retries = 3

    # The minimum delay between request retries.
    min-backoff = 200ms

    # The maximum delay between request retries.
    max-backoff = 10s

    # Random jitter factor applied to retry delay calculation.
    random-factor = 0.0
  }

  # Settings specific to S3 multipart uploads.
  multipart-upload {
    retry-settings = ${alpakka.s3.retry-settings}
  }
}

For record, the following are the log of AWS CLI ls and Alpakka S3 connector listBucket respectively.
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>scolionet-archive</Name><Prefix></Prefix><MaxKeys>10000</MaxKeys><Delimiter>/</Delimiter><IsTruncated>false</IsTruncated><KeyCount>0</KeyCount></ListBucketResult>

I1230 12:21:27  6549 filer_client.go:113] read directory: directory:"/buckets" limit:2147483647
I1230 12:21:27  6549 s3api_handlers.go:89] status 200 application/xml: <?xml version="1.0" encoding="UTF-8"?>
<ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Owner><DisplayName></DisplayName><ID></ID></Owner><Buckets></Buckets></ListAllMyBucketsResult>

Found the problem. Need to set path-style access, rather than virtual host-style access in configuration.

Thanks for the update!


PlotBar() with "consecutive_X_vals: True" option

Hi!
It is a common case when we need to visualize XY data pairs on a Bar graph. However, often we need to show the Y-values/bars side-by-side of each others, therefore we need to code extra lines not to directly use the raw X-values for the PlotBar() methode.
Example what I need to do now for this:
double[] xs = { 0, 5, 10, 20, 40, 80 };
double[] ys = { 0.02, 0.01, 0.01, 0.02, 0.04, 0.03 };
int barCount = xs.Length;
//artificial X values to make Bars side by side without data gaps in X-axis:
double[] x_consecutive = DataGen.Consecutive(barCount);

// make the bar plot
formsPlot1.plt.PlotBar(x_consecutive, ys);

// apply custom axis tick labels
formsPlot1.plt.XTicks(x_consecutive, xs.Select(item => item.ToString()).ToArray());
formsPlot1.Render();

It would be great to have an extra parameter for the PlotBar() method, like "consecutive_X_vals". If this set to True, the plot would take the string representations of the X-values, and plot the Y-values side by side, with labels from the X-values.
In this way we avoid the extra required coding.
Thanks! :)

Hi @bukkideme,
Summarizing your request, you'd like an easy way to display a series of Ys in a bar plot without having to go through the trouble of creating Xs. This seems like a common task, and that it should be easier to figure out than it currently is!
I think if you pass in null for xs it will produce the behavior you're looking for, but I recognize this is poorly documented...
https://github.com/swharden/ScottPlot/blob/8119f0f7795d38f1d659a9f09b8384537a87f14c/src/ScottPlot/Plottable/BarPlot.cs#L47
There's a chance I'll be refining the plottable-creating methods (toward simpler ones with more expressive names, #638) so maybe there's a way we can make this more intuitive somehow. Perhaps reversing the arguments and giving them more expressive names?
/// <summary>
/// Add a bar plot from a series of values
/// </summary>
Plottable.BarPlot AddBar(
    double[] values,
    double[] positions = null,
    Color? color = null,
    string label = null,
    bool autoAxis = true)

Hi @Benny121221,
I made this a little easier since the issue was first raised 👍
double[] values = ScottPlot.DataGen.Random(rand, count);
plt.AddBar(values);

string[] labels = Enumerable.Range(1, count).Select(x => $"bar number {x}").ToArray();
plt.XTicks(labels);
plt.XAxis.TickLabelStyle(rotation: 45);