Repeat address for tokens

Related Safe Addresses

0x5b21e1e3cb1ea2c28589e7141066181a6a9bf9d5
0x5b28a7f4cb62032c91f2b651e85625f75decadcd
0x5b40a53d4971f6ff7b1ffcd470031545a7091e8a
0x5b47f5039ea27563973add429a0c10a0d9bba478
0x5b49d5d6b842db3328f5f80fc1a89c257c1a30b5
0x5b4a6ab4b6615598128a5f3278001074b9237041
0x5b503edf4b0f92dad741c4e46849a280aa2379c4
0x5b5be7a2510e4f21362b678607f29ff2ef571ab1
0x5b66859c9549a5e38262cd650b22c74e8d3116ba
0x5b670957de25c26995e59da306bbd05c699fd50c
0x5b6acecacd7855441fe31b6b64a9cb3b446d6f95
0x5b707439115fea9eda7b31e766aa4827f168ca03
0x5b7773098f5a6c7af9d862c41dd844588f5278fe
0x5b7dae771c0fd1775aca16151a791df81080e5d7
0x5b7ee5e185ccbc119ca0d9ae56e17f168ab31ffc
0x5b7fd84eba978203ac91d14dd7c79e8fe4c6f1cf
0x5b8a2428667f9bbb7c4ae6ff115b63ac8451b956
0x5b8cb6c255441e2b35da86bbb35f3dd273153ebb
0x5b9047b9261020f72757edd4b7fb2e6bf82de178
0x5b9a707d1db580b3cff8ee18418ddcfa4cdd514f
0x5ba9b850b634b45c716d85abfb1151d30ba802c2

-->

# Reasoning

<!--
I found these safes with 1 transaction from 1 wallet,and the wallet is 0x421f3dac4fe3bd06fa4d51c53647511aeb8ccf69

so I checked this wallet's txs,and then find these safes are from one person
-->

# Methodology

<!--

The reported addresses were discovered by checking irregularities in the number of Safe transactions made via Dune. Based on the resulting list of Safes, a dataset was built that categorized each Safe transaction. Based on that, an algorithm was used to identify repeating patterns in the order of those interactions.

the main wallet's records:
https://etherscan.io/address/0x421f3dac4fe3bd06fa4d51c53647511aeb8ccf69

I sorted the excel by the amount of eligible SAFE tokens. I identified that there are some addresses eligible of exactly the same amount of tokens . and i found txs were from 1 same wallet

-->

# Safe Address

<!--

0x51C852fF1790EB30C6fCEFe9C1a1EF650CECc830

-->

Reasoning
I found these safes with 1 transaction from 1 wallet,and the wallet is 0x421f3dac4fe3bd06fa4d51c53647511aeb8ccf69

I don't understand what this means.
Looking at the first 3 Safes, I'm unable to see a pattern, looks rather like legitimate use to me.
https://gnosis-safe.io/app/eth:0x5b21e1e3cb1ea2c28589e7141066181a6a9bf9d5/transactions/history
https://gnosis-safe.io/app/eth:0x5b28a7f4cb62032c91f2b651e85625f75decadcd/transactions/history
https://gnosis-safe.io/app/eth:0x5b40a53d4971f6ff7b1ffcd470031545a7091e8a/transactions/history


Posterior samples have wrong shape

Hi again,
I have a simulator which takes 4 input parameters which all have different distributions. My prior is a list of 4 pytorch distributions.
If I train a direct posterior and try to sample n samples from it, the samples are of shape (n, 1) and not (n, 4).
posterior.sample((num2sample,), show_progress_bars=False)
Out[10]:
tensor([[1.9223e+15],
        [4.1910e+04],
        [5.0085e-02],
        ...,
        [3.0099e+05],
        [2.4742e+15],
        [3.9000e-02]])

If I draw samples form the prior they are returned correctly:
sim.prior.sample(10)
Out[7]:
tensor([[3.8090e+14, 2.3983e+05, 1.7250e+04, 1.2737e-02],
        [1.8061e+15, 5.9933e+04, 1.5600e+04, 3.6108e-02],
        [3.8849e+14, 2.9748e+05, 1.1851e+04, 2.9004e-02],
        [2.0855e+15, 2.1721e+05, 1.1178e+04, 1.4964e-02],
        [1.2729e+15, 1.9187e+04, 1.2657e+04, 1.2392e-02],
        [2.2269e+15, 1.0568e+05, 1.8403e+04, 2.5195e-02],
        [2.2742e+14, 2.1631e+05, 1.3004e+04, 2.2265e-02],
        [1.7049e+15, 4.7677e+03, 1.5740e+04, 4.6073e-02],
        [2.5384e+15, 2.6011e+05, 1.9843e+04, 1.0162e-02],
        [6.5650e+14, 1.3132e+05, 1.8876e+04, 4.1541e-02]], dtype=torch.float64)

I checked the posterior's attributes and the posterior._prior._event_shape = 4 and posterior._prior._batch_shape = [].
Do you know why I have this problem?

Hi Florian,
it seems the parameter dimension was not inferred correctly.
The prior you pass to sbi should behave like a PyTorch prior, however, your sim.prior.sample(10) does not (should be (10,) as arg). That could be a reason.
What is the shape of the parameters sampled from posterior._prior?

Actually I can sample from my prior by passing just an int as the number of samples or a tuple defining the shape:
sim.prior.sample(10)
Out[2]:
tensor([[8.2421e+14, 2.4276e+05, 1.8725e+04, 3.5713e-03],
        [2.7103e+15, 1.4338e+05, 1.7596e+04, 5.4472e-02],
        [8.4460e+14, 1.2252e+05, 1.0656e+04, 2.2900e-02],
        [2.4678e+15, 2.7206e+04, 1.7520e+04, 2.2662e-02],
        [1.3584e+15, 1.7171e+05, 1.8944e+04, 4.9961e-02],
        [2.7679e+15, 2.0074e+04, 1.2571e+04, 1.8497e-02],
        [2.4697e+15, 1.2816e+05, 1.4488e+04, 1.2973e-02],
        [3.7542e+14, 2.6672e+05, 1.3568e+04, 3.1359e-02],
        [3.5961e+14, 1.6905e+04, 1.4236e+04, 3.3936e-02],
        [2.5946e+15, 2.8394e+05, 1.7771e+04, 5.5826e-02]], dtype=torch.float64)

# that's the same as:
sim.prior.sample((10,))
Out[3]:
tensor([[4.7052e+14, 2.5984e+05, 1.3158e+04, 2.4655e-03],
        [1.5594e+15, 1.8605e+05, 1.9996e+04, 3.4619e-02],
        [2.2753e+15, 4.0866e+04, 1.2856e+04, 1.1775e-02],
        [1.0762e+15, 1.8317e+05, 1.2778e+04, 2.3503e-02],
        [2.2822e+15, 6.6867e+04, 1.7473e+04, 1.3355e-02],
        [1.6209e+15, 6.2214e+04, 1.3102e+04, 5.3320e-03],
        [1.2519e+15, 1.4508e+05, 1.0706e+04, 9.9415e-03],
        [1.2796e+15, 1.4787e+05, 1.8617e+04, 3.8143e-02],
        [2.7023e+15, 4.0455e+04, 1.1984e+04, 4.8649e-02],
        [1.4761e+15, 2.8272e+05, 1.8696e+04, 5.0003e-02]], dtype=torch.float64)

If I sample from the posterior._prior I get the following output:
posterior._prior.sample(10)
Out[4]:
tensor([[2.4010e+15, 2.0739e+05, 1.1759e+04, 2.7014e-02],
        [5.2388e+14, 5.5951e+04, 1.1292e+04, 3.4990e-02],
        [2.2223e+15, 2.5039e+05, 1.5002e+04, 2.4063e-02],
        [1.0604e+15, 2.2279e+05, 1.2265e+04, 6.0208e-02],
        [3.0185e+14, 8.5896e+04, 1.0947e+04, 3.5420e-02],
        [2.7360e+15, 2.4920e+05, 1.3871e+04, 4.1933e-02],
        [7.2969e+14, 2.5875e+05, 1.5856e+04, 2.1702e-02],
        [2.1154e+15, 5.2478e+03, 1.9399e+04, 2.4853e-02],
        [6.2179e+14, 6.1339e+04, 1.7909e+04, 3.4079e-02],
        [5.0034e+14, 1.2789e+05, 1.3542e+04, 2.2617e-02]])

# or from a tuple input:
posterior._prior.sample((10,))
Out[5]:
tensor([[8.5037e+14, 7.3460e+04, 1.0069e+04, 1.6706e-02],
        [2.1490e+15, 2.9720e+04, 1.2406e+04, 2.2737e-02],
        [2.3552e+15, 1.8865e+05, 1.5927e+04, 4.9095e-02],
        [1.0328e+15, 2.6924e+05, 1.2311e+04, 4.0301e-02],
        [2.5763e+15, 1.9828e+05, 1.4717e+04, 4.1474e-02],
        [1.6521e+15, 6.1534e+04, 1.4594e+04, 5.6483e-03],
        [2.5671e+15, 2.4800e+05, 1.3198e+04, 2.3369e-02],
        [1.6641e+15, 2.2994e+05, 1.0638e+04, 7.2256e-03],
        [2.4976e+15, 1.5705e+05, 1.1053e+04, 2.5414e-02],
        [1.1703e+15, 9.9143e+04, 1.7963e+04, 4.2549e-02]])

Hi Jan,
Sorry for bothering you with my problem, but any suggestions on how to solve that issue? I couldn't find a solution yet :/
If you think my prior is the problem, I coul send you my prior class if that helps.
Thanks in advance,
Florian

Hi Florian,
This behaviour of the posterior is puzzling.
Debug hints:

pass a list of independent torch priors instead of your prior class and see if the problem remains.
assuming you are using snpe, look into the code of posterior_nn, the function used to build the function that builds the neural net from samples theta and x. Access the posterior.net attribute and check the output shape of the Flow. It should be the prior shape.

@Fololo any news on this front? Is this due to the way your prior is defined, or more an issue with sbi?

Hi @janfb,
sorry for not beeing responsive for so long. My internship already ended and I didn't have time to work on it until today.
I found out that if I pass my "raw prior" as a list of torch distributions to sbi I get the following error:
AssertionError: One of the distributions you passed is defined over a scalar only. Make
        sure pass distributions with one of event_shape or batch_shape > 0: For example
            - instead of Uniform(0.0, 1.0) pass Uniform(torch.zeros(1), torch.ones(1))
            - instead of Beta(1.0, 2.0) pass Beta(tensor([1.0]), tensor([2.0])).

Indeed, I initialized my prior on single numeric inputs. Changing that to passing a torch.tensor as recommended in the error message solved my problem. Sampling from the posterior works now.
Thank you for your help once again :)

No problem. Great, then this is solved!


Update configuring-your-server-to-receive-payloads.md

Why:

What's being changed:

Check off the following:

[ ] All of the tests are passing.
[ ] I have reviewed my changes in staging. (look for the deploy-to-heroku link in your pull request, then click View deployment)
[ ] For content changes, I have reviewed the localization checklist
[ ] For content changes, I have reviewed the Content style guide for GitHub Docs.

Thanks for opening a PR 👍 Please fill out the pull request template in the top comment in this pull request, then we'll get this up for review!


CASMINST-6099: VCS backup/restore: Linting and minor improvements

Description

Mostly linting. Also added a table of contents to the page, and modified one set of commands to avoid the user having to manually edit the backed-up manifest files. I tested this last procedure on wasp.
Checklist

[X] If I added any command snippets, the steps they belong to follow the prompt conventions (see example).
[X] If I added a new directory, I also updated .github/CODEOWNERS with the corresponding team in Cray-HPE.
[X] My commits or Pull-Request Title contain my JIRA information, or I do not have a JIRA.

/backport release/1.4 release/1.3


CreateUiDefinition -  PasswordBoxes Must Have Min Length - Not picking up minimum length

Setup
Parameter created in bicep ..
@secure()
@minLength(8)
param accessToken string

.. produces JSON output ..
"parameters": {
    "accessToken": {
      "type": "secureString",
      "minLength": 8
    }

CreateUIDefinition PasswordBox ..
{
    "name": "accessToken",
    "type": "Microsoft.Common.PasswordBox",
    "label": {
        "password": "My Access Token",
        "confirmPassword": "Confirm access token"
    },
    "toolTip": "Your access token",
    "constraints": {
        "required": true,
        "regex": "^.{8,}$",
        "validationMessage": "Must be greater than 8 characters."
    },
    "options": {
        "hideConfirmation": false
    },
    "visible": true
}

Error
[-] PasswordBoxes Must Have Min Length (25 ms)
PasswordBox 'accessToken' regex does not have a minimum length of 12

Discussion
Code does not detect the regex correctly. (^.{8}$ also fails).

I think this is working as expected, the minLength of the password should be 12 chars - your repro only shows 8...  If you change it to twelve does it work as expected?

@stephenpope - just checking to see if this is still an issue for you?

Sorry for the delay on this.
I checked again. 12 works ok :)

Cool - thanks for confirming...


On Big Sur, my triggers (keyboard shortcuts) stopped working

I have tried adding Quicksilver to the Security&Privacy SystemPreferences-pane, adding it under Input Monitoring (it was already added to Full Disk Access, Files and Folders, Accessibility [although not to Automation?] ).
I have tried restarting Quicksilver, rebooting, but absolutely no reaction.
An example of a trigger that i use often is to trigger a search from text that i have selected. The trigger uses the selected text and does a search on a database that i have to check like 20 times a day, so this would help a lot in my workflow.
I have been using QS from the start and am refusing to go with any other utility because i love it.
But this really needs to be fixed!
Thanks.

I’ve never used (or even noticed) Input Monitoring and triggers are working fine for me.
I suppose the first thing I would check is that you have the current version (1.6.1). If you’ve been using it from the start, I know there were at least two versions where the auto-updates broke, so a lot of people are running old copies.

They have been working for me since first beta of Big Sur, and now on an Air M1.  What is failing, is Clipboard History

Not to hijack this issue, but what about Clipboard history? I have the panel docked to a screen edge and it sometimes gets confused, but other than that, it functions.

OK, I have no idea why I hadn't tried reinstalling the app yet.. facepalm
Everything works now! YAY I'm so glad i can still be using this amazing tool!!

OK. So i realised that all my triggers work, EXCEPT the one i use most: the 'find with' trigger, which i use to search a website.
I have even fully uninstalled quicksilver and all its preferences, reinstalled everything, but same result.
I've got the trigger setup in the following way:
Select an item:
Current Selection
Action:
Find With...
Target:
The website address with a search query where i have it end in *** to be replaced with the current selected text.
Somehow, this trigger won't do anything.
All the other triggers do work.
It's independent of what key combo i assign it to.
If i set the trigger to 'Show Window' when triggered, it does show that quicksilver tries to do something, but nothing actually happens..
I have also tried setting up a new trigger with as basic a setting as any (ie: using the standard https://www.google.com/search?q=*** )
but still no dice
Anyone can help out?

If you just call up “Current Selection” in Quicksilver, does it grab the expected thing? If not, I would re-check the access it has under Accessibility and Automation.

no, it does not. But it has access under the syspref-pane..

OK, so i figured out it does work in the Finder. In System preferences under Automation, that is the only application thats listed as being accessible to Quicksilver. There is no way to manually add other Apps.
seems that is the problem i guess??

There is no way to manually add other Apps.

I think this is the same as it has been since 10.14: It will ask you if you want to allow Apple Events from Quicksilver to another application. The alert might appear behind Quicksilver. If you don’t answer in 30 seconds, the system assumes “No” and never asks you again.
See https://qsapp.com/manual/FAQ/#actions-fail-on-mojave-or-later
I haven’t revisited the topic in a while, so you should check around for tips. I think it might be possible to do more fine-grained things with tccutil, so check that as well before resetting everything with brute force.

So this appears to be an issue with either:
a) the 'get current selection' trigger not working; or
b) Quicksilver requesting permission, but not being authorized in time.
Are these things that we can change, or are we at the mercy of the OS?
We have #2646 related to the current selection action. Can we close this?

We’re at the mercy of the OS for most of it. I know getting the selection was working when this issue was created. Not so sure now, but I need to do more testing.

I've been getting intermittent problems because of 'Security' settings recently. The way that I solve this is by 'removing' the 'Quicksilver' entry from the Accessibility pane, and then dragging Quicksilver.app (from my /Applications folder) back into this pane. That seems to reset permissions for me.

@captainmacnl - could you try that and see if it solves your problem?

By the way, I had to add Quicksilver also to Input Monitoring for Triggers to work.

@debugDS - can you take a screenshot of where you changed these settings? I'm not aware of this, but it could be a newer macOS thing.
We may need to explicitly allow this permission in Quicksilver to make triggers work by default.
Thanks

My system is in french but i'm sure you can find your way.

Ça marche, merci! :)
I've created a new issue here: #2684 specifically regarding this 'Input Monitoring' issue. I'll close this issue and keep that one open.
Quicksilver 2.0 will released within the next 24 which should fix the majority of issues as outlined in this post. A fix for not having to manually enable 'Input Monitoring' will be in Quicksilver 2.1.


Print offenses when failure

Currently when Rubocop finds offenses it raises an exception and that is
it. With this change it will print out the offenses to let the user know
why it's failing.
Today the output looks like this when there's a failure
Traceback (most recent call last):
	1: from ./index.rb:139:in `<main>'
./index.rb:132:in `run': unhandled exception

With this PR the output will look like this
2 offense(s) found
L17-L17:Style/StringConcatenation: Prefer string interpolation to string concatenation.
L17-L17:Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols.
Traceback (most recent call last):
	1: from ./index.rb:138:in `<main>'
./index.rb:130:in `run': Rubocop found offenses (RuntimeError)

I'm using this workflow for one of my repos and I didn't understand why it was failing, hence making this change. I'm not used to writing Ruby so feel free to change the style of the code.

@luizfonseca Any chance to get this merged?

Oh, did I miss this PR 🤔  -- Yep, just going to test it quickly.

@simeg You should be able to get this update in the version 1.5.6 of the action (latest)


[BUG] Update the opensearch-dashboards-functional-test repo with current tests.

What is the bug?
The opensearch-dashboards-functional-test 2.x and 2.6 branches need to be updated with the current cypress tests.
PR https://github.com/opensearch-project/opensearch-dashboards-functional-test/pull/486 added them to the 2.5 branch, but the backport failed to 2.x. As a result, those tests were not included when the new branch was cut from 2.x for the 2.6 release.
The opensearch-dashboards-functional-test main branch also needs to be updated, but it's currently set to version 3.0 while security analytics is still on 2.6.

The main branch of the FTR has been updated with the most recent cypress tests for the plugin
https://github.com/opensearch-project/opensearch-dashboards-functional-test/pull/622


MediaStreamAudioDestinationNode

As promised I'm working on a toy WebRTC implementation (continuing discussion from https://github.com/orottier/web-audio-api-rs/pull/106#issuecomment-1048601898 )
I realized I needed the MediaStreamAudioDestinationNode for this.
To summarize:

MediaStreamAudioSourceNode: allows you to ship AudioBuffers into the AudioContext
MediaStreamAudioDestinationNode: allows you to ship AudioBuffers out of the AudioContext

Both of them utilize the MediaStream iterator we have defined in our project as a shim for the w3c MediaStream. I think it plays out nicely

Appart my small comments, (and assuming again my poor knowledge of the possible problems that can occur with streaming :) it looks good to me


Behavior of various recent GATConv and PytGeo versions for PPI

🐛 Bug
A performance difference in loss and accuracy for PPI/GAT across recent software versions (1.6.1, 1.6.3), but not GAT versions (Jun19, Oct12).
Description
I recently upgraded to version 1.6.3, and saw spikier behavior (in the loss and performance curves) than I’d seen before on both my GAT-based application and then the PPI test application (c.f. https://github.com/rusty1s/pytorch_geometric/issues/1478).
One thing led to another, and seeing what looked like different loss/accuracy performance as well, I decided to write a test program which:

is run in multiple conda environments to test installed PytGeo software (I have 2 envs: 'DL38' with software installed 9/2/2020, and 'pyt_pyg_jan11'  with software installed 1/11/2021)
runs a GAT-based model with different versions of GATConv (I am testing Jun19 and Oct12 versions)
runs training/val/test for multiple trials and epochs (here, 15 trials and 500 epochs)
trains PPI.py similarly to the example program.  Items such as the model parameters, loss function, and optimizer are fixed here.

Stats
The test results are for 2 environments x 2 GATConv versions/environment x 15 trials/GATConv version; 500 epochs per trial.
There are 6 metrics that are captured: (loss, val_f1 and test_f1) x (final [Epoch 500] and best [min loss or max accuracy across epochs]).  Across the (15) trials, the mean and standard deviation of these stats are shown.

Conda Env
GATVersion
Stat
lossfinal
val_f1final
test_f1final
lossmin
val_f1max
test_f1max

DL38
Jun19
mean
0.120
90.34%
92.43%
0.109
91.02%
93.08%

DL38
Jun19
std
0.036
2.03%
2.05%
0.003
0.52%
0.30%

DL38
Oct12
mean
0.109
90.92%
92.99%
0.108
91.09%
93.14%

DL38
Oct12
std
0.004
0.46%
0.37%
0.004
0.37%
0.32%

pyt_pyg_jan11
Jun19
mean
0.154
87.74%
89.66%
0.147
88.26%
90.19%

pyt_pyg_jan11
Jun19
std
0.016
1.17%
1.14%
0.008
0.74%
0.69%

pyt_pyg_jan11
Oct12
mean
0.150
87.81%
89.77%
0.148
88.00%
89.97%

pyt_pyg_jan11
Oct12
std
0.019
1.46%
1.42%
0.017
1.31%
1.30%

Plots
I also wrote a plotting program which plots all of these results together, giving Nenvs=2 x Nversions=2 subplots, each subplot with Ntrials=15 (loss, val_acc, test_acc) curves.

Takeaway
The table and plots show that the change in GATConv does not affect performance, for this PPI example.  However, there is a different in the software baseline that affects mean accuracy by about 3%.
To Reproduce
Here is the test program that I used.  Run this in 1 or more environments; it gives a pandas table of PPI GATConv results and a PKL file with details that can be plotted later.  On my computer, it takes ~ 3 hours to generate results in 1 environment, for 2 GATConv versions, 15 trials and 500 epochs.
I can post the code for plotting as well, if desired.

Python code for running test

import logging
import os
import os.path as osp
import sys
from datetime import datetime
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import torch
import pickle
import torch.nn.functional as F
from sklearn.metrics import f1_score
from torch_geometric.data import DataLoader
from torch_geometric.datasets import PPI
#from torch_geometric.nn import GATConv

# imports to support GAT-Conv
from typing import Union, Tuple, Optional
from torch_geometric.typing import (OptPairTensor, Adj, Size, NoneType, OptTensor)
from torch import Tensor
from torch.nn import Parameter, Linear
from torch_sparse import SparseTensor, set_diag
from torch_geometric.nn.conv import MessagePassing
from torch_geometric.utils import remove_self_loops, add_self_loops, softmax
from torch_geometric.nn.inits import glorot, zeros

path = osp.join(osp.dirname(osp.realpath(__file__)), '..', 'data', 'PPI')
train_dataset = PPI(path, split='train')
val_dataset = PPI(path, split='val')
test_dataset = PPI(path, split='test')

bs, nheads, nheads_f, nhidden = 8, 2, 4, 64
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

train_loader = DataLoader(train_dataset, batch_size=bs, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=bs, shuffle=False)
test_loader = DataLoader(test_dataset, batch_size=bs, shuffle=False)

def set_logging(dir_out):
    level    = logging.INFO
    format   = '  %(message)s'
    handlers = [logging.FileHandler(dir_out + 'filename.log'), logging.StreamHandler()]
    logging.basicConfig(level = level, format = format, handlers = handlers)

class GATConv_Jun19(MessagePassing):
    _alpha: OptTensor
    def __init__(self, in_channels: Union[int, Tuple[int, int]],
                 out_channels: int, heads: int = 1, concat: bool = True,
                 negative_slope: float = 0.2, dropout: float = 0.,
                 add_self_loops: bool = True, bias: bool = True, **kwargs):
        super(GATConv_Jun19, self).__init__(aggr='add', node_dim=0, **kwargs)

        self.in_channels = in_channels
        self.out_channels = out_channels
        self.heads = heads
        self.concat = concat
        self.negative_slope = negative_slope
        self.dropout = dropout
        self.add_self_loops = add_self_loops

        if isinstance(in_channels, int):
            self.lin_l = Linear(in_channels, heads * out_channels, bias=False)
            self.lin_r = self.lin_l
        else:
            self.lin_l = Linear(in_channels[0], heads * out_channels, False)
            self.lin_r = Linear(in_channels[1], heads * out_channels, False)

        self.att_l = Parameter(torch.Tensor(1, heads, out_channels))
        self.att_r = Parameter(torch.Tensor(1, heads, out_channels))

        if bias and concat:
            self.bias = Parameter(torch.Tensor(heads * out_channels))
        elif bias and not concat:
            self.bias = Parameter(torch.Tensor(out_channels))
        else:
            self.register_parameter('bias', None)

        self._alpha = None

        self.reset_parameters()

    def reset_parameters(self):
        glorot(self.lin_l.weight)
        glorot(self.lin_r.weight)
        glorot(self.att_l)
        glorot(self.att_r)
        zeros(self.bias)

    def forward(self, x: Union[Tensor, OptPairTensor], edge_index: Adj,
                size: Size = None, return_attention_weights=None):
        # type: (Union[Tensor, OptPairTensor], Tensor, Size, NoneType) -> Tensor  # noqa
        # type: (Union[Tensor, OptPairTensor], SparseTensor, Size, NoneType) -> Tensor  # noqa
        # type: (Union[Tensor, OptPairTensor], Tensor, Size, bool) -> Tuple[Tensor, Tuple[Tensor, Tensor]]  # noqa
        # type: (Union[Tensor, OptPairTensor], SparseTensor, Size, bool) -> Tuple[Tensor, SparseTensor]  # noqa
        r"""

        Args:
            return_attention_weights (bool, optional): If set to :obj:`True`,
                will additionally return the tuple
                :obj:`(edge_index, attention_weights)`, holding the computed
                attention weights for each edge. (default: :obj:`None`)
        """
        H, C = self.heads, self.out_channels

        x_l: OptTensor = None
        x_r: OptTensor = None
        alpha_l: OptTensor = None
        alpha_r: OptTensor = None
        if isinstance(x, Tensor):
            assert x.dim() == 2, 'Static graphs not supported in `GATConv`.'
            x_l = x_r = self.lin_l(x).view(-1, H, C)
            alpha_l = alpha_r = (x_l * self.att_l).sum(dim=-1)
        else:
            x_l, x_r = x[0], x[1]
            assert x[0].dim() == 2, 'Static graphs not supported in `GATConv`.'
            x_l = self.lin_l(x_l).view(-1, H, C)
            alpha_l = (x_l * self.att_l).sum(dim=-1)
            if x_r is not None:
                x_r = self.lin_r(x_r).view(-1, H, C)
                alpha_r = (x_r * self.att_r).sum(dim=-1)

        assert x_l is not None
        assert alpha_l is not None

        if self.add_self_loops:
            if isinstance(edge_index, Tensor):
                num_nodes = x_l.size(0)
                num_nodes = size[1] if size is not None else num_nodes
                num_nodes = x_r.size(0) if x_r is not None else num_nodes
                edge_index, _ = remove_self_loops(edge_index)
                edge_index, _ = add_self_loops(edge_index, num_nodes=num_nodes)
            elif isinstance(edge_index, SparseTensor):
                edge_index = set_diag(edge_index)

        # propagate_type: (x: OptPairTensor, alpha: OptPairTensor)
        out = self.propagate(edge_index, x=(x_l, x_r),
                             alpha=(alpha_l, alpha_r), size=size)

        alpha = self._alpha
        self._alpha = None

        if self.concat:
            out = out.view(-1, self.heads * self.out_channels)
        else:
            out = out.mean(dim=1)

        if self.bias is not None:
            out += self.bias

        if isinstance(return_attention_weights, bool):
            assert alpha is not None
            if isinstance(edge_index, Tensor):
                return out, (edge_index, alpha)
            elif isinstance(edge_index, SparseTensor):
                return out, edge_index.set_value(alpha, layout='coo')
        else:
            return out

    def message(self, x_j: Tensor, alpha_j: Tensor, alpha_i: OptTensor,
                index: Tensor, ptr: OptTensor,
                size_i: Optional[int]) -> Tensor:
        alpha = alpha_j if alpha_i is None else alpha_j + alpha_i
        alpha = F.leaky_relu(alpha, self.negative_slope)
        alpha = softmax(alpha, index, ptr, size_i)
        self._alpha = alpha
        alpha = F.dropout(alpha, p=self.dropout, training=self.training)
        return x_j * alpha.unsqueeze(-1)

    def __repr__(self):
        return '{}({}, {}, heads={})'.format(self.__class__.__name__,
                                             self.in_channels,
                                             self.out_channels, self.heads)

class GATConv_Oct12(MessagePassing):
    _alpha: OptTensor

    def __init__(self, in_channels: Union[int, Tuple[int, int]],
                 out_channels: int, heads: int = 1, concat: bool = True,
                 negative_slope: float = 0.2, dropout: float = 0.,
                 add_self_loops: bool = True, bias: bool = True, **kwargs):
        kwargs.setdefault('aggr', 'add')
        super(GATConv_Oct12, self).__init__(node_dim=0, **kwargs)

        self.in_channels = in_channels
        self.out_channels = out_channels
        self.heads = heads
        self.concat = concat
        self.negative_slope = negative_slope
        self.dropout = dropout
        self.add_self_loops = add_self_loops

        if isinstance(in_channels, int):
            self.lin_l = Linear(in_channels, heads * out_channels, bias=False)
            self.lin_r = self.lin_l
        else:
            self.lin_l = Linear(in_channels[0], heads * out_channels, False)
            self.lin_r = Linear(in_channels[1], heads * out_channels, False)

        self.att_l = Parameter(torch.Tensor(1, heads, out_channels))
        self.att_r = Parameter(torch.Tensor(1, heads, out_channels))

        if bias and concat:
            self.bias = Parameter(torch.Tensor(heads * out_channels))
        elif bias and not concat:
            self.bias = Parameter(torch.Tensor(out_channels))
        else:
            self.register_parameter('bias', None)

        self._alpha = None

        self.reset_parameters()

    def reset_parameters(self):
        glorot(self.lin_l.weight)
        glorot(self.lin_r.weight)
        glorot(self.att_l)
        glorot(self.att_r)
        zeros(self.bias)

    def forward(self, x: Union[Tensor, OptPairTensor], edge_index: Adj,
                size: Size = None, return_attention_weights=None):
        # type: (Union[Tensor, OptPairTensor], Tensor, Size, NoneType) -> Tensor  # noqa
        # type: (Union[Tensor, OptPairTensor], SparseTensor, Size, NoneType) -> Tensor  # noqa
        # type: (Union[Tensor, OptPairTensor], Tensor, Size, bool) -> Tuple[Tensor, Tuple[Tensor, Tensor]]  # noqa
        # type: (Union[Tensor, OptPairTensor], SparseTensor, Size, bool) -> Tuple[Tensor, SparseTensor]  # noqa
        r"""

        Args:
            return_attention_weights (bool, optional): If set to :obj:`True`,
                will additionally return the tuple
                :obj:`(edge_index, attention_weights)`, holding the computed
                attention weights for each edge. (default: :obj:`None`)
        """
        H, C = self.heads, self.out_channels

        x_l: OptTensor = None
        x_r: OptTensor = None
        alpha_l: OptTensor = None
        alpha_r: OptTensor = None
        if isinstance(x, Tensor):
            assert x.dim() == 2, 'Static graphs not supported in `GATConv`.'
            x_l = x_r = self.lin_l(x).view(-1, H, C)
            alpha_l = (x_l * self.att_l).sum(dim=-1)
            alpha_r = (x_r * self.att_r).sum(dim=-1)
        else:
            x_l, x_r = x[0], x[1]
            assert x[0].dim() == 2, 'Static graphs not supported in `GATConv`.'
            x_l = self.lin_l(x_l).view(-1, H, C)
            alpha_l = (x_l * self.att_l).sum(dim=-1)
            if x_r is not None:
                x_r = self.lin_r(x_r).view(-1, H, C)
                alpha_r = (x_r * self.att_r).sum(dim=-1)

        assert x_l is not None
        assert alpha_l is not None

        if self.add_self_loops:
            if isinstance(edge_index, Tensor):
                num_nodes = x_l.size(0)
                if x_r is not None:
                    num_nodes = min(num_nodes, x_r.size(0))
                if size is not None:
                    num_nodes = min(size[0], size[1])
                edge_index, _ = remove_self_loops(edge_index)
                edge_index, _ = add_self_loops(edge_index, num_nodes=num_nodes)
            elif isinstance(edge_index, SparseTensor):
                edge_index = set_diag(edge_index)

        # propagate_type: (x: OptPairTensor, alpha: OptPairTensor)
        out = self.propagate(edge_index, x=(x_l, x_r),
                             alpha=(alpha_l, alpha_r), size=size)

        alpha = self._alpha
        self._alpha = None

        if self.concat:
            out = out.view(-1, self.heads * self.out_channels)
        else:
            out = out.mean(dim=1)

        if self.bias is not None:
            out += self.bias

        if isinstance(return_attention_weights, bool):
            assert alpha is not None
            if isinstance(edge_index, Tensor):
                return out, (edge_index, alpha)
            elif isinstance(edge_index, SparseTensor):
                return out, edge_index.set_value(alpha, layout='coo')
        else:
            return out

    def message(self, x_j: Tensor, alpha_j: Tensor, alpha_i: OptTensor,
                index: Tensor, ptr: OptTensor,
                size_i: Optional[int]) -> Tensor:
        alpha = alpha_j if alpha_i is None else alpha_j + alpha_i
        alpha = F.leaky_relu(alpha, self.negative_slope)
        alpha = softmax(alpha, index, ptr, size_i)
        self._alpha = alpha
        alpha = F.dropout(alpha, p=self.dropout, training=self.training)
        return x_j * alpha.unsqueeze(-1)

    def __repr__(self):
        return '{}({}, {}, heads={})'.format(self.__class__.__name__,
                                             self.in_channels,
                                             self.out_channels, self.heads)

class Net(torch.nn.Module):
    def __init__(self, version):
        super(Net, self).__init__()
        self.version = version
        GATConv = {'Jun19': GATConv_Jun19, 'Oct12': GATConv_Oct12}[version]
        self.conv1 = GATConv(train_dataset.num_features, nhidden, heads=nheads)
        self.lin1 = torch.nn.Linear(train_dataset.num_features, nheads * nhidden)
        self.conv2 = GATConv(nheads * nhidden, nhidden, heads=nheads)
        self.lin2 = torch.nn.Linear(nheads * nhidden, nheads * nhidden)
        self.conv3 = GATConv(nheads * nhidden, train_dataset.num_classes, heads=nheads_f, concat=False)
        self.lin3 = torch.nn.Linear(nheads * nhidden, train_dataset.num_classes)

    def forward(self, x, edge_index):
        x = F.elu(self.conv1(x, edge_index) + self.lin1(x))
        x = F.elu(self.conv2(x, edge_index) + self.lin2(x))
        x = self.conv3(x, edge_index) + self.lin3(x)
        return x

def train(loader, model, loss_op, optimizer):
    model.train()

    total_loss = 0
    for data in loader:
        data = data.to(device)
        optimizer.zero_grad()
        preds = model(data.x, data.edge_index)
        loss = loss_op(preds, data.y)
        total_loss += loss.item() * data.num_graphs
        loss.backward()
        optimizer.step()
    return total_loss / len(loader.dataset)

@torch.no_grad()
def test(loader, model):
    model.eval()

    ys, preds = [], []
    for data in loader:
        ys.append(data.y)
        out = model(data.x.to(device), data.edge_index.to(device))
        preds.append((out > 0).float().cpu())

    y, pred = torch.cat(ys, dim=0).numpy(), torch.cat(preds, dim=0).numpy()
    return f1_score(y, pred, average='micro') if pred.sum() > 0 else 0

def plot_results(Res, j_trial, dir_out, title):
    fig, ax = plt.subplots(figsize=(8, 6))
    plt.plot(Res[:,0], Res[:,1], label='Loss', linewidth=2)
    plt.plot(Res[:,0], Res[:,2], label='Val F1', linewidth=2)
    plt.plot(Res[:,0], Res[:,3], label='Test F1', linewidth=2)
    plt.legend()
    ax.set_ylim(0, 1); ax.grid(True); plt.title(title);
    plt.tight_layout()
    plt.savefig('./%s/figure_%d.png' % (dir_out, j_trial))
    plt.clf()

def run_training(GAT_version, j_trial, Nepochs, dir_out):
    model = Net(GAT_version).to(device)
    loss_op = torch.nn.BCEWithLogitsLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=0.005)

    torch.manual_seed(j_trial)
    np.random.seed(j_trial)

    Res = np.zeros((Nepochs,4))
    loss_min, val_f1_max, test_f1_max = 1e6, -1e6, -1e6
    for epoch in range(1, Nepochs+1):
        loss = train(train_loader, model, loss_op, optimizer)
        val_f1 = test(val_loader, model)
        test_f1 = test(test_loader, model)

        if loss < loss_min: loss_min = loss
        if val_f1  > val_f1_max: val_f1_max = val_f1
        if test_f1 > test_f1_max: test_f1_max = test_f1

        logging.info('Version={:s} Trial: {:2d} Epoch: {:02d}   Loss: {:.4f}, Val: {:.4f}, Test: {:.4f}    BEST: Loss: {:.4f}, Val: {:.4f}, Test: {:.4f}'.format(
            GAT_version, j_trial, epoch, loss, val_f1, test_f1, loss_min, val_f1_max, test_f1_max))
        Res[epoch-1,:] = np.array([epoch, loss, val_f1, test_f1])
    plot_results(Res, j_trial, dir_out, 'PPI: BS=%d, nheads=%d/%d, nhidden=%d, seed=%d' % (bs, nheads, nheads_f, nhidden, j_trial))
    final_results = {'loss_final': loss, 'val_f1_final':val_f1, 'test_f1_final':test_f1,
        'loss_min':loss_min, 'val_f1_max': val_f1_max, 'test_f1_max': test_f1_max}
    return final_results, Res

if __name__ == "__main__":
    conda = sys.executable.split('/')[-3]  # get the conda environment name.
    dir_out = './results/%s/%s/' % (conda, datetime.now().strftime("%m-%d_%H.%M.%S")) # output directory for the training.
    os.makedirs(dir_out, exist_ok=True)
    set_logging(dir_out)

    Ntrials, Nepochs = 15, 500
    Res_all = {}
    for i_version, GAT_version in enumerate(['Jun19', 'Oct12']):
        for j_trial in range(Ntrials):
            final_results, Res = run_training(GAT_version, j_trial, Nepochs, dir_out)
            Res_all[(conda, i_version, GAT_version, j_trial)] = Res # Store all of the results
            if j_trial==0:
                df = pd.DataFrame(columns=list(final_results.keys()))
            df = df.append(final_results, ignore_index=True)
        logging.info(df)
        # accumulate mean/std into a dataframe, for each GAT_version.
        mean = df.mean().to_frame().T
        std  = df.std().to_frame().T
        stats = mean.append(std)
        stats.insert(0, "Stat", ['mean', 'std'], True)
        stats.insert(0, "GAT_Version", [GAT_version]*2, True)
        stats_all = stats if (i_version==0) else stats_all.append(stats)
    # insert the conda environment name into the dataframe.
    stats_all.insert(0, "Conda", [conda]*4, True)
    logging.info(stats_all)

    # save results to a file.
    fname_pkl = 'ppi_gat_%s.pkl' % (conda)
    with open(fname_pkl, 'wb') as f:
        pickle.dump((Res_all, stats_all), f)

Expected Behavior
GAT performance stays the same or gets better for PPI.py example over time, but not worse.
Environment

OS: Ubuntu 20.04
Python version: 3.8
PyTorch version: 1.6
PyTorch Geometric version: 1.6.1 and 1.6.3
CUDA/cuDNN version: 10.1
GCC version: 8.4

| DL38 | pyt_pyg_jan11
-- | -- | --
pytorch | 1.6.0 | 1.7.1
torch-cluster | 1.5.7 | 1.5.8
torch-geometric | 1.6.1 | 1.6.3
torch-scatter | 2.0.5 | 2.0.5
torch-sparse | 0.6.7 | 0.6.8
torch-spline-conv | 1.2.0 | 1.2.0
torchvision | 0.7.0 | 0.8.2
Additional context
Let me know if there is additional information I can supply, to help clarify or debug the issue.  Also, if there is a somewhat easy way to install known pytgeo configurations, I can try more environments if that’s helpful in isolating the issue.

Thanks for this in-depth issue. Note that PyTorch Geometric 1.6.0/1.6.1 (fixed in 1.6.2) introduced a bug to GATConv where attention coefficients were computed in a slightly wrong fashion. Therefore, I would have expected the performance of GATConv to drop in torch-geometric==1.6.1.
Nonetheless, I just re-ran the examples/ppi.py script, and cannot see any spikes in performance myself. Final performance is around Val F1: 95.70 and Test F1: 97.20 (which is in line with the results reported in the official paper).

Thanks for this in-depth issue. Note that PyTorch Geometric 1.6.0/1.6.1 (fixed in 1.6.2) introduced a bug to GATConv where attention coefficients were computed in a slightly wrong fashion. Therefore, I would have expected the performance of GATConv to drop in torch-geometric==1.6.1.
Nonetheless, I just re-ran the examples/ppi.py script, and cannot see any spikes in performance myself. Final performance is around Val F1: 95.70 and Test F1: 97.20 (which is in line with the results reported in the official paper).

Thanks @rusty1s.  I had noticed the bugfixes and changes to GATConv over the last several months, which is what led me to set this up so that both GATConv versions could be run in both 1.6.1 and 1.6.3, to try and understand why performance was changing.
The results above used the following parameters (_t=trn, _v=val, _f=final stage):

bs_t, bs_v, nheads, nheads_f, nhidden = 8, 8, 2, 4, 64

Based on your comments - here are results using the the values in the standard ppi.py example (running 3 trials instead of 15):

bs_t, bs_v, nheads, nheads_f, nhidden = 1, 2, 4, 6, 256

Conda Env
GATVersion
Stat
lossfinal
val_f1final
test_f1final
lossmin
val_f1max
test_f1max

DL38 (1.6.1)
Jun19
mean
0.060
93.44%
95.26%
0.005
98.08%
98.85%

DL38
Jun19
std
0.043
3.96%
3.36%
0.000
0.09%
0.04%

DL38
Oct12
mean
0.006
97.74%
98.67%
0.005
98.18%
98.95%

DL38
Oct12
std
0.001
0.16%
0.13%
0.000
0.09%
0.06%

pyt_pyg_jan11 (1.6.3)
Jun19
mean
0.020
96.66%
97.74%
0.019
96.97%
98.03%

pyt_pyg_jan11
Jun19
std
0.002
0.33%
0.32%
0.001
0.05%
0.07%

pyt_pyg_jan11
Oct12
mean
0.022
96.74%
97.72%
0.020
96.90%
97.90%

pyt_pyg_jan11
Oct12
std
0.000
0.04%
0.06%
0.000
0.14%
0.16%

All of these cases give a best-case test_f1 within ~1%, with the best being 98.95% for the (1.6.1 SW baseline, 1.6.3 GATConv).  Your (95.7, 97.2) numbers are for 100 epochs; the comparable numbers above are (96.74, 97.72), the mean across 3 trials for 500 epochs.
Here is the corresponding plot of the loss and accuracy:

In this issue, I'm not focused as much on the spike-behavior as the change in accuracy.
Based on the all of the data above, it seems to me that something has changed in the software baseline between 1.6.1 and 1.6.3, outside of the changes in GATConv, that affects training performance for batch_size > 1.
I don't know how to debug this issue directly (any ideas?), but I'm certainly willing to try and install SW versions as they were on certain dates, to try and narrow in on when a non-GATConv change may have been made to affect this performance (especially for batch_size >1).  But, given the torch-geometric install procedure and recent changes to that, I'm not exactly sure how to do that reliably (any ideas?).

Thanks @rusty1s.  I had noticed the bugfixes and changes to GATConv over the last several months, which is what led me to set this up so that both GATConv versions could be run in both 1.6.1 and 1.6.3, to try and understand why performance was changing.
The results above used the following parameters (_t=trn, _v=val, _f=final stage):

bs_t, bs_v, nheads, nheads_f, nhidden = 8, 8, 2, 4, 64

Based on your comments - here are results using the the values in the standard ppi.py example (running 3 trials instead of 15):

bs_t, bs_v, nheads, nheads_f, nhidden = 1, 2, 4, 6, 256

Conda Env
GATVersion
Stat
lossfinal
val_f1final
test_f1final
lossmin
val_f1max
test_f1max

DL38 (1.6.1)
Jun19
mean
0.060
93.44%
95.26%
0.005
98.08%
98.85%

DL38
Jun19
std
0.043
3.96%
3.36%
0.000
0.09%
0.04%

DL38
Oct12
mean
0.006
97.74%
98.67%
0.005
98.18%
98.95%

DL38
Oct12
std
0.001
0.16%
0.13%
0.000
0.09%
0.06%

pyt_pyg_jan11 (1.6.3)
Jun19
mean
0.020
96.66%
97.74%
0.019
96.97%
98.03%

pyt_pyg_jan11
Jun19
std
0.002
0.33%
0.32%
0.001
0.05%
0.07%

pyt_pyg_jan11
Oct12
mean
0.022
96.74%
97.72%
0.020
96.90%
97.90%

pyt_pyg_jan11
Oct12
std
0.000
0.04%
0.06%
0.000
0.14%
0.16%

All of these cases give a best-case test_f1 within ~1%, with the best being 98.95% for the (1.6.1 SW baseline, 1.6.3 GATConv).  Your (95.7, 97.2) numbers are for 100 epochs; the comparable numbers above are (96.74, 97.72), the mean across 3 trials for 500 epochs.
Here is the corresponding plot of the loss and accuracy:

In this issue, I'm not focused as much on the spike-behavior as the change in accuracy.
Based on the all of the data above, it seems to me that something has changed in the software baseline between 1.6.1 and 1.6.3, outside of the changes in GATConv, that affects training performance for batch_size > 1.
I don't know how to debug this issue directly (any ideas?), but I'm certainly willing to try and install SW versions as they were on certain dates, to try and narrow in on when a non-GATConv change may have been made to affect this performance (especially for batch_size >1).  But, given the torch-geometric install procedure and recent changes to that, I'm not exactly sure how to do that reliably (any ideas?).

Here is some additional information.  I created three new conda environments as follows, with (XXX, YYY) = (160, 1.6.0), (161, 1.6.1) and (162, 1.6.2).
conda create --name pgXXX python=3.8
conda activate pgXXX
conda install pytorch==1.6.0 torchvision==0.7.0 cudatoolkit=10.1 -c pytorch
conda install pandas numpy scipy matplotlib

pip install --no-index torch-scatter -f https://pytorch-geometric.com/whl/torch-1.6.0+cu101.html
pip install --no-index torch-sparse -f https://pytorch-geometric.com/whl/torch-1.6.0+cu101.html
pip install --no-index torch-cluster -f https://pytorch-geometric.com/whl/torch-1.6.0+cu101.html
pip install --no-index torch-spline-conv -f https://pytorch-geometric.com/whl/torch-1.6.0+cu101.html
pip install torch-geometric==YYY

Then, I ran the test with Ntrials = 3; Nepochs = 500; bs_t, bs_v, nheads, nheads_f, nhidden = 8, 8, 2, 4, 64, similar to the first post, not the second one.  Here are the results; pg160 and pg161 are better than pg162.

Conda Env
GATConvVersion
Stat
lossfinal
val_f1final
test_f1final
lossmin
val_f1max
test_f1max

pg160
Jun19
mean
0.108
90.98%
93.17%
0.107
91.05%
93.22%

pg160
Jun19
std
0.005
0.69%
0.51%
0.005
0.64%
0.50%

pg160
Oct12
mean
0.109
91.03%
92.97%
0.108
91.19%
93.12%

pg160
Oct12
std
0.003
0.31%
0.31%
0.003
0.29%
0.32%

pg161
Jun19
mean
0.119
90.11%
92.44%
0.109
90.78%
93.04%

pg161
Jun19
std
0.017
1.23%
1.26%
0.003
0.23%
0.29%

pg161
Oct12
mean
0.109
90.69%
92.73%
0.107
91.15%
93.16%

pg161
Oct12
std
0.001
0.78%
0.65%
0.001
0.19%
0.24%

pg162
Jun19
mean
0.147
87.88%
90.00%
0.146
88.05%
90.13%

pg162
Jun19
std
0.004
0.58%
0.44%
0.005
0.45%
0.37%

pg162
Oct12
mean
0.194
84.13%
86.04%
0.145
88.40%
90.37%

pg162
Oct12
std
0.062
5.07%
5.10%
0.017
1.37%
1.48%

Summarizing the data above, here is the mean of test_f1_max, for my 5 environments, for the two GATConv versions.  (I think max is better for comparison here, it helps to negate the effect of the spikes, but the conclusion is the same for other metrics.)  It would appear that something (non-GATConv) changed in version 1.6.2 that affects the performance, for batch_size > 1.

mean, test_f1_max
pg1603 trials
DL38 (1.6.1)15 trials
pg1613 trials
pg1623 trials
pyt_pyg_jan11 (1.6.3)15 trials

Jun19 GATConv (in 1.6.1)
93.22%
93.08%
93.04%
90.13%
90.19%

Oct12 GATConv (in 1.6.2)
93.12%
93.14%
93.16%
90.37%
89.97%

Here is what conda list torch* shows for my 5 environments:
| pg160 | DL38 | pg161 | pg162 | pyt_pyg_jan11
-- | -- | -- | -- | -- | --
pytorch | 1.6.0 | 1.6.0 | 1.6.0 | 1.7.1 | 1.7.1
torch-cluster | 1.5.8 | 1.5.7 | 1.5.8 | 1.5.8 | 1.5.8
torch-geometric | 1.6.0 | 1.6.1 | 1.6.1 | 1.6.2 | 1.6.3
torch-scatter | 2.0.5 | 2.0.5 | 2.0.5 | 2.0.5 | 2.0.5
torch-sparse | 0.6.8 | 0.6.7 | 0.6.8 | 0.6.8 | 0.6.8
torch-spline-conv | 1.2.0 | 1.2.0 | 1.2.0 | 1.2.0 | 1.2.0
torchvision | 0.7.0 | 0.7.0 | 0.7.0 | 0.8.2 | 0.8.2

Here is some additional information.  I created three new conda environments as follows, with (XXX, YYY) = (160, 1.6.0), (161, 1.6.1) and (162, 1.6.2).
conda create --name pgXXX python=3.8
conda activate pgXXX
conda install pytorch==1.6.0 torchvision==0.7.0 cudatoolkit=10.1 -c pytorch
conda install pandas numpy scipy matplotlib

pip install --no-index torch-scatter -f https://pytorch-geometric.com/whl/torch-1.6.0+cu101.html
pip install --no-index torch-sparse -f https://pytorch-geometric.com/whl/torch-1.6.0+cu101.html
pip install --no-index torch-cluster -f https://pytorch-geometric.com/whl/torch-1.6.0+cu101.html
pip install --no-index torch-spline-conv -f https://pytorch-geometric.com/whl/torch-1.6.0+cu101.html
pip install torch-geometric==YYY

Then, I ran the test with Ntrials = 3; Nepochs = 500; bs_t, bs_v, nheads, nheads_f, nhidden = 8, 8, 2, 4, 64, similar to the first post, not the second one.  Here are the results; pg160 and pg161 are better than pg162.

Conda Env
GATConvVersion
Stat
lossfinal
val_f1final
test_f1final
lossmin
val_f1max
test_f1max

pg160
Jun19
mean
0.108
90.98%
93.17%
0.107
91.05%
93.22%

pg160
Jun19
std
0.005
0.69%
0.51%
0.005
0.64%
0.50%

pg160
Oct12
mean
0.109
91.03%
92.97%
0.108
91.19%
93.12%

pg160
Oct12
std
0.003
0.31%
0.31%
0.003
0.29%
0.32%

pg161
Jun19
mean
0.119
90.11%
92.44%
0.109
90.78%
93.04%

pg161
Jun19
std
0.017
1.23%
1.26%
0.003
0.23%
0.29%

pg161
Oct12
mean
0.109
90.69%
92.73%
0.107
91.15%
93.16%

pg161
Oct12
std
0.001
0.78%
0.65%
0.001
0.19%
0.24%

pg162
Jun19
mean
0.147
87.88%
90.00%
0.146
88.05%
90.13%

pg162
Jun19
std
0.004
0.58%
0.44%
0.005
0.45%
0.37%

pg162
Oct12
mean
0.194
84.13%
86.04%
0.145
88.40%
90.37%

pg162
Oct12
std
0.062
5.07%
5.10%
0.017
1.37%
1.48%

Summarizing the data above, here is the mean of test_f1_max, for my 5 environments, for the two GATConv versions.  (I think max is better for comparison here, it helps to negate the effect of the spikes, but the conclusion is the same for other metrics.)  It would appear that something (non-GATConv) changed in version 1.6.2 that affects the performance, for batch_size > 1.

mean, test_f1_max
pg1603 trials
DL38 (1.6.1)15 trials
pg1613 trials
pg1623 trials
pyt_pyg_jan11 (1.6.3)15 trials

Jun19 GATConv (in 1.6.1)
93.22%
93.08%
93.04%
90.13%
90.19%

Oct12 GATConv (in 1.6.2)
93.12%
93.14%
93.16%
90.37%
89.97%

Here is what conda list torch* shows for my 5 environments:
| pg160 | DL38 | pg161 | pg162 | pyt_pyg_jan11
-- | -- | -- | -- | -- | --
pytorch | 1.6.0 | 1.6.0 | 1.6.0 | 1.7.1 | 1.7.1
torch-cluster | 1.5.8 | 1.5.7 | 1.5.8 | 1.5.8 | 1.5.8
torch-geometric | 1.6.0 | 1.6.1 | 1.6.1 | 1.6.2 | 1.6.3
torch-scatter | 2.0.5 | 2.0.5 | 2.0.5 | 2.0.5 | 2.0.5
torch-sparse | 0.6.8 | 0.6.7 | 0.6.8 | 0.6.8 | 0.6.8
torch-spline-conv | 1.2.0 | 1.2.0 | 1.2.0 | 1.2.0 | 1.2.0
torchvision | 0.7.0 | 0.7.0 | 0.7.0 | 0.8.2 | 0.8.2

The only changes I can think of that should have effects on GATConv were some modifications  to torch_geometric.utils.softmax. I‘m guessing that these changes may explain the different performances.

The only changes I can think of that should have effects on GATConv were some modifications  to torch_geometric.utils.softmax. I‘m guessing that these changes may explain the different performances.

Thanks @rusty1s, and I see this has an active fix at #2013, nice!   To test/finish, I implemented a slightly different version of the same program, but using 3 different versions of torch_geometric.utils.softmax instead of 2 versions of GATConv.  The 3 softmax versions are from 1.6.1, 1.6.2, and the version that you just submitted today.  I ran in 1.6.1, 1.6.2, and pyt_pyg_Jan11 environments.  Here are the results (Ntrials=3), it looks good!

Conda
softmaxversion
Stat
lossfinal
val_f1final
test_f1final
lossmin
val_f1max
test_f1max

pg161
161
mean
0.1304
89.41%
91.56%
0.1077
90.90%
93.03%

pg161
161
std
0.0378
2.84%
2.49%
0.0026
0.48%
0.33%

pg161
162
mean
0.1341
89.13%
91.01%
0.1331
89.25%
91.10%

pg161
162
std
0.0268
1.94%
2.12%
0.0265
2.05%
2.18%

pg161
Jan14
mean
0.1396
85.01%
86.84%
0.1075
91.17%
93.09%

pg161
Jan14
std
0.0502
9.60%
9.82%
0.0023
0.30%
0.35%

pg162
161
mean
0.1143
90.48%
92.63%
0.1071
91.13%
93.27%

pg162
161
std
0.0050
0.97%
0.91%
0.0046
0.38%
0.41%

pg162
162
mean
0.1830
85.32%
87.17%
0.1406
88.85%
90.68%

pg162
162
std
0.0637
5.32%
5.28%
0.0097
0.80%
0.84%

pg162
Jan14
mean
0.1087
91.05%
93.04%
0.1073
91.14%
93.12%

pg162
Jan14
std
0.0014
0.30%
0.37%
0.0013
0.27%
0.36%

[Jan11]
161
mean
0.1092
90.93%
92.91%
0.1077
91.05%
93.03%

[Jan11]
161
std
0.0016
0.27%
0.39%
0.0013
0.26%
0.33%

[Jan11]
162
mean
0.1507
87.67%
89.65%
0.1489
87.86%
89.84%

[Jan11]
162
std
0.0056
0.40%
0.36%
0.0060
0.51%
0.43%

[Jan11]
Jan14
mean
0.1103
90.81%
92.82%
0.1087
90.90%
92.89%

[Jan11]
Jan14
std
0.0023
0.31%
0.48%
0.0003
0.19%
0.38%

Thanks @rusty1s, and I see this has an active fix at #2013, nice!   To test/finish, I implemented a slightly different version of the same program, but using 3 different versions of torch_geometric.utils.softmax instead of 2 versions of GATConv.  The 3 softmax versions are from 1.6.1, 1.6.2, and the version that you just submitted today.  I ran in 1.6.1, 1.6.2, and pyt_pyg_Jan11 environments.  Here are the results (Ntrials=3), it looks good!

Conda
softmaxversion
Stat
lossfinal
val_f1final
test_f1final
lossmin
val_f1max
test_f1max

pg161
161
mean
0.1304
89.41%
91.56%
0.1077
90.90%
93.03%

pg161
161
std
0.0378
2.84%
2.49%
0.0026
0.48%
0.33%

pg161
162
mean
0.1341
89.13%
91.01%
0.1331
89.25%
91.10%

pg161
162
std
0.0268
1.94%
2.12%
0.0265
2.05%
2.18%

pg161
Jan14
mean
0.1396
85.01%
86.84%
0.1075
91.17%
93.09%

pg161
Jan14
std
0.0502
9.60%
9.82%
0.0023
0.30%
0.35%

pg162
161
mean
0.1143
90.48%
92.63%
0.1071
91.13%
93.27%

pg162
161
std
0.0050
0.97%
0.91%
0.0046
0.38%
0.41%

pg162
162
mean
0.1830
85.32%
87.17%
0.1406
88.85%
90.68%

pg162
162
std
0.0637
5.32%
5.28%
0.0097
0.80%
0.84%

pg162
Jan14
mean
0.1087
91.05%
93.04%
0.1073
91.14%
93.12%

pg162
Jan14
std
0.0014
0.30%
0.37%
0.0013
0.27%
0.36%

[Jan11]
161
mean
0.1092
90.93%
92.91%
0.1077
91.05%
93.03%

[Jan11]
161
std
0.0016
0.27%
0.39%
0.0013
0.26%
0.33%

[Jan11]
162
mean
0.1507
87.67%
89.65%
0.1489
87.86%
89.84%

[Jan11]
162
std
0.0056
0.40%
0.36%
0.0060
0.51%
0.43%

[Jan11]
Jan14
mean
0.1103
90.81%
92.82%
0.1087
90.90%
92.89%

[Jan11]
Jan14
std
0.0023
0.31%
0.48%
0.0003
0.19%
0.38%

Glad that it is now working as intented! Thanks so much for your efforts! Really appreciate it.

Glad that it is now working as intented! Thanks so much for your efforts! Really appreciate it.


deserialize CiString as plain type

As in the title, adding #[serde(transparent)] would allow to Serialize and Deserialize CiString as it was a String type.
let j = json!("Foo");
let s: CiString = serde_json::from_value(j);

Thanks for this. Can you up the version number to 0.4.0 and put the change in changes.md? Once done I'll merge and release fix to crates.io

Hi @gregelenbaas, I made what you asked in the latest commit.
If you merge this I could also fix in a short time Clippy: Default impl is missing for CiString and also write some tests in separate PRs. Maybe you can release to crates.io after these changes in order to have only one version bump.
Let me know what you think about

Sure, I'll merge in this change now and wait a week for you to get your other pr up. Thank you for contributing!


BUG: Detect multiline, aline, and so on.

Version (please complete the following information):

OS: Windows 11
Browser: Microsoft Edge
Web Clipper version: 0.9.5
Obsidian version: 1.7.5

Describe the bug
A clear and concise description of what the bug is. If applicable, add screenshots to help explain your problem.
In this plugin, MathJax blocks are parsed into LaTeX and imported into Obsidian enclosed in $ or $$, but multi-line equations are not displayed correctly.
To reproduce
Steps to reproduce the behavior:

Open https://mathjax.github.io/MathJax-demos-web/equation-numbers.html
Click the extension button and clip the page
Equations display will be corrupted.

Expected behavior
A clear and concise description of what you expected to happen.
For the following equation,

I expect the extension to parse below.
$$
\begin{align*}
a_{1} & = b_{1} + c_{1} \\ a_{2} & = b_{2} + c_{2} - d_{2} + e_{2}
\end{align*}
$$

Actual behavior
$$
a_{1} & = b_{1} + c_{1} \\ a_{2} & = b_{2} + c_{2} - d_{2} + e_{2}
$$

Your template file
Go to your template in Web Clipper settings and click on "Export". Attach the JSON file here, or paste the content below.

Your change via #142 is in 0.9.6

#142 is not directly related to this issue.
Some of these expressions do not render correctly in Obsidian even though they are recognized as math blocks.
I understand that some of this is due to the limitations of the mathml-to-latex package, but it would be helpful to have minimal support for multilines, alignments, etc.

Ok the should be more clarity in the difference with #121


Exception  Google Service Exception

Environment details

OS: Windows
PHP version: 7.3
Package name and version: google/apiclient V 2.0
Framework:Lumen

Steps to reproduce
Trying avoid Exception setAccessToken if expire token is used but it return HTTP STATUS Code 500
Remember: this token received from App back-end just validate it.i've already read others ssues..
Note Issue: only occur this error when expire token is used...How to Avoid to used Expire Token?
try{
            $this->client->setAccessToken($token);
        }catch (Exception $e){
               echo  'sad';die;

        }

But not Catch Exception How to Catch error.

i found the solution
using GuzzleHttp
        $url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' . $token;
        $httpService->get($url);


Upgrade Celery to version 4.0.2

This will need rebase after #1802 is merged

FYI, travis doesn't look very happy.

PR updated. I rebased to get the new periodic tasks we had in the meantime. I also included the djcelery removal parts to make Travis happy. Once we merge #1802 we'd need to rebase.

This PR should be good to go with the last comments.

PR updated, with the two changes on base_env_vars.py.

PR rebased for the recent settings changes.

PR rebased after #1802 merge


Implement scroll while dragging

See https://github.com/bevacqua/dragula/pull/449#issuecomment-430645737

Another option:
https://www.bennadel.com/blog/3460-automatically-scroll-the-window-when-the-user-approaches-the-viewport-edge-in-javascript.htm


Why TEMP is not defined?

I followed your instructions, but I receive: Uncaught ReferenceError: TEMP is not defined.
main.js:
var app = new PLAYGROUND.Application({     render: TEMP.showDimensions,     container: 'svg-container' });

It's not the part of the library. It's just a piece of code to show dimensions in examples. If you want it then just copy/paste that on top of your code. Although I am not sure if this is something you want as you seem to be toying with SVGs and this is Canvas based.
var TEMP = {};

TEMP.showDimensions = function() {
    this.container.style.background = "#000";
    this.layer.clear("#026");

    this.layer.fillStyle("#fff").font("16px Arial");
    this.layer.textAlign("center");

    this.layer.stars(16, this.center.y, 0.5, 0.5, Math.PI / 2, 1.0)
    this.layer.fillText(this.height + " px", 0, 0);
    this.layer.restore();

    this.layer.stars(this.center.x, this.height - 8, 0.5, 0.5, 0, 1.0)
    this.layer.fillText(this.width + " px", 0, 0);
    this.layer.restore();

    this.layer.stars(this.center.x, this.center.y, 0.5, 0.5, 0, 1.0)
    this.layer.fillText("x " + this.scale.toFixed(2), 0, 0);
    this.layer.restore();
}

I would like to draw a grid and use the scale as shown in the examples makerjs.

Scaling the whole application window will not give you the results you want. There is a lot of experimentation ahead of you to get that effect. You have to draw the lines manually and the scale is really the gap between them. Something to get you started from top of my head:
playground({

    render() {

    	this.layer.clear("#0af");

    	let cols = 10;
    	let rows = 10;

    	let gap = 32;

    	for(let x = 0; x < cols; x++) {

    		this.layer.moveTo(x * 32, 0);
    		this.layer.lineTo(x * 32, this.height);

    	}

    	for(let y = 0; y < rows; y++) {

    		this.layer.moveTo(0, y * 32);
    		this.layer.lineTo(this.width, y * 32);

    	}

    }

});

You have to multiply gap by scale and calculate number of rows and cols depending on screen size. Not as easy as it first looked like but I am sure you will manage to find the solution after some experimentation.

I would also post a question on stackoverflow asking "How to draw an infinite zoom grid like this using canvas" because maybe I am overengineering that.

Thank you for taking the time, probably it will not suit me.


How do you know what options there are?

I am building a wish list app and wanted to use a todo app as my data. (first tried Wunderlist, but because Microsoft bought it, it is now death. Let's hope they don't do the same thing with this platform)
I found your demo project and am spitting that one out to see what you use. I found changing .completed.get_stats() to .query(['today']) gets me all items in the Today view. This helped me find my list ID (wish list ID, which is<PHONE_NUMBER>) and now I want to query only that list, but I don't see any options.
Is there a list of all the possible options. The default Todoist API is no help either.

Same question was asked in the official Todoist repo https://github.com/Doist/todoist-python/issues/37
The short answer:
DEPRECATED: query endpoint is deprecated for a long time and this
        method will be removed in the next major version of todoist-python

You should sync and filter items into your code. Is it the best option? probably not.
They also have a REST API 🎉 under development, still in beta: https://developer.todoist.com/rest/v8

@Cosmitar thanks again, the REST API is exactly what I need and seems much easier than the rest. I already got all my todos render on the page!
If anyone else is looking to get something similar done, here is my Axios code for Vue.js
https://gist.github.com/mvaneijgen/dad0b500c53b8d188c93dde4a6c71d9b


platform_device_id -> org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50

The package is not supported for the Latest Kotlin versions.
current configuration
  **
  platform_device_id: ^1.0.1
  **

buildscript {
    ext.kotlin_version = '1.7.10'
    repositories {
        google()
        mavenCentral()
    }
}

Error while building:
FAILURE: Build failed with an exception.

* What went wrong:
The Android Gradle plugin supports only Kotlin Gradle plugin version 1.5.20 and higher.
The following dependencies do not satisfy the required version:
project ':platform_device_id' -> org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50

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

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

BUILD FAILED in 5s
Running Gradle task 'assembleRelease'...                            6.2s
Gradle task assembleRelease failed with exit code 1

This is not going to be fixed dude, the author has abandoned the project. You have to see the pull request section like #47

@Rajatkumar0662
@stan-at-work
try this fork:
https://github.com/faridfedora/platform_device_id_kotlin_updated

or just add these lines to your dependency:
  platform_device_id:
    git:
      url: https://github.com/faridfedora/platform_device_id_kotlin_updated.git
      ref: main


ak.unflatten should take an axis argument

So that you don't have to do this:
structure = ak.Array([[0], [2, 1]])
counts0 = ak.num(structure)
counts1 = ak.flatten(structure)
values = ak.Array([3,4,5])
array = ak.unflatten(ak.unflatten(values, counts1), counts0)

(It also came up in the Million Song Dataset prep.)

What would you do instead if axis were available?

Oh, not this example. This isn't adding a jagged dimension to structure, it's transporting that to a completely new array. Sorry, I jumped to a conclusion. I'll provide the example I saw.

original = ak.Array([[1, 2, 3, 4], [], [5, 6, 7], [8, 9]])
desired = ak.Array([[[1, 2], [3, 4]], [], [[5], [6, 7]], [[8], [9]]])

given
counts = ak.Array([2, 2, 1, 2, 1, 1])

Currently, you have to
ak.unflatten(ak.unflatten(ak.flatten(original), counts), [2, 0, 2, 2])

in which the [2, 0, 2, 2] is determined somehow from the ak.num(original) and the counts.
We'd like to be able to just
ak.unflatten(original, counts, axis=1)


Add Example for Slider Labels in Taipy GUI

Added an example demonstrating how to implement slider labels using a dictionary and lov in Taipy GUI.

Hi @FabienLelaquais, I have fixed according to your suggestions expect https://github.com/Avaiga/taipy/pull/2077#pullrequestreview-2375714887

Hi @FredLL-Avaiga, the requested changes have been made. Please take a look, and let me know if any further adjustments are needed based on your time.

Hi @FredLL-Avaiga,
Are we good to merge this PR (and 2159) before Hacktoberfest, maybe after getting approval from @FabienLelaquais?

Yes indeed we can accept this.
I'm not sure we need the second example though: I see no added value compared to the 'Select among a list of values' example already in the doc. But we will certainly reuse the first one.
Well done @JeevaRamanathan! and thank you.

@jrobinAV can you merge this ?

@JeevaRamanathan Thank you for your contribution !!

@JeevaRamanathan, congratulations on this merged PR.
Could you please contact me by mail to prepare your swag<EMAIL_ADDRESS>

I appreciate your help & support @FredLL-Avaiga,  @FabienLelaquais, @joaoandre, @RymMichaut! Thank you very much!


plop -i twice crashes

thank you for reporting thing 👍

You're welcome!
And thanks for your project, I just tried it, it's amazing!

Getting this as well

Thanks!


Good things to have

Posting this here, feel free to move
Before the system becomes too complex, it would be great to be able to have the following:

global random seed
being able to get training + test results for each primitive per template (maybe through a flag)

The 29 june 2018 commit by @ckxz105 to the template-2018-june branch modified the config file to include training and test during search. We actually need to refactor this functionality as not to interfere with evaluation.

Done


Regarding custom config from examples page

this it shows only .css file and his config file, but he uses custom modules that are not attached, does anyone know how  can i obtain them ? I know its not an actual bug from Waybar, but i think this would be best place to ask, since it example 1 on the example page and i cant get to work.

here  you can see how it looks on my screen. I dont know where to get those custom modules that are referenced in his .config file.


refactor(edge-compute): enforce es6 good practices

close #3935

@chiptus seems that there is a conflict on this one after the introduction of #3987  although I don't know why as it should not have affected the edge module.


Proposal: Include JSConf '14 demo examples under the RuntimeJS github organization

@iefserge the demo examples, specifically the command line examples like ls and echo were really interesting. Any chance those could be added under the runtimeJS organization on GitHub?

They were removed because runtime no longer attempts to implement Unix-like shell and utilities, instead they can be added as an external modules. It's a large chunk of work to fully implement those commands.


Add Dask to coverage tests

Signed-off-by: Devin Petersohn<EMAIL_ADDRESS>
What do these changes do?

[ ] passes flake8 modin
[ ] passes black --check modin
[ ] signed commit with git commit -s
[ ] Resolves #?
[ ] tests added and passing

blocked on #1176


updating a primary key in a trigger not possible?

Let me explain my situation.
I have two tables: users and app_states.
app_states replaces a local state library. Thus it is used in many components. A typical way to fetch the state is:
const { results: appState } = useLiveQuery(
  db.app_states.liveUnique({
    where: { user_email: authUser?.email },
  }),
)

Due to https://github.com/electric-sql/electric/issues/1132 I had to make a user's email the primary key of the app_states table. Otherwise when fetching using liveFirst electric-sql made my components rerender perpetually.
But I have now run into a problem caused by this circumvention:
To ensure the email is always correct I use this trigger:
CREATE TRIGGER IF NOT EXISTS users_app_states_email_trigger
  AFTER UPDATE OF email ON users
BEGIN
  UPDATE app_states SET user_email = NEW.email
  WHERE user_id = NEW.user_id;
END;

The problem is that when this runs, the following error occurs:
Error: cannot rollback - no transaction is active

I also tried to: 1. create a new app_state using the NEW.xxx data, then deleting the old one inside the trigger. Same error.
So it seems that updating a primary key in a trigger is not possible? Is this a problem in sqlite or in electric-sql?
(I realize that it is a bit weird to update a primary key. But hey, this is only the app state row, so not a data integrity deal. And it's just because of the liveFirst rerender issue)
A different method would be to change the user_email to reference user.email with on update update.  But that is not allowed in electric-sql (yet) as far as I know.

In case someone else finds this: the docs explicitely say, that primary keys can not be updated: https://electric-sql.com/docs/usage/data-modelling/constraints#referential-integrity:

To preserve referential integrity Electric prevents updates to a table's primary keys.


spring-boot-oauth2-pkce can't work correctly. There's a logic problem. Can you solve it?

if set:
   @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        super.configure(oauthServer);
//        //支持post形式的client认证
        oauthServer.allowFormAuthenticationForClients();
...

then there is a ClientCredentialsTokenEndpointFilter in the TokenEndpointAuthenticationFilters like this orders of the "/oauth/token" endpoint's filterchain：
...

ClientCredentialsTokenEndpointFilter
BasicAuthenticationFilter
...

the logic can not go through the ClientCredentialsTokenEndpointFilter's logic.

I do not quite understand what you are trying to do.
Could you describe your actions, the result obtained and the expected result?

Hi, I have run into this issue as well.
I get this trace when trying to get a token. It looks like it is trying to do user authentication...
This is with:

Spring Boot 2.2.6
Spring 5.2.2.RELEASE
Sping Security OAUth2 2.3.9.release

Steve
`2020-04-05 19:13:22.435 DEBUG 12539 --- [nio-8085-exec-6] o.s.security.web.FilterChainProxy        : /oauth/token at position 5 of 12 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
2020-04-05 19:13:22.435 DEBUG 12539 --- [nio-8085-exec-6] p.c.ClientCredentialsTokenEndpointFilter : Request is to process authentication
2020-04-05 19:14:34.947  WARN 12539 --- [nio-8085-exec-9] o.s.s.c.bcrypt.BCryptPasswordEncoder     : Encoded password does not look like BCrypt
2020-04-05 19:14:34.948 DEBUG 12539 --- [nio-8085-exec-9] o.s.s.a.dao.DaoAuthenticationProvider    : Authentication failed: password does not match stored value
2020-04-05 19:14:34.949 DEBUG 12539 --- [nio-8085-exec-9] p.c.ClientCredentialsTokenEndpointFilter : Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
org.springframework.security.authentication.BadCredentialsException: Bad credentials
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.additionalAuthenticationChecks(DaoAuthenticationProvider.java:93)
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:166)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:175)
at org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter.attemptAuthentication(ClientCredentialsTokenEndpointFilter.java:123)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
`

According to the stack trace, I can only see that the problem is in client authentication and most likely is caused by an incorrect configuration of the client details service, which I could not reproduce when using the specific configuration from the example.
I close this ticket due to lack of details to reproduce the problem.


OnDataChanged, OnDataRemoved, OnDataAdded method errors

Hello! I have some exceptional problems with these three methods. There is application, that must get publications from the server and create listview from them. Ii have two listviews and two publications(inprocess and finished) . Each element of listview is request for a courier, where courier have "Finish" button that finish the request. And that's the code:
SERVER:
// android publications
Meteor.publish('applicationsMobileInprocess', function() {
//check(status, String);
//var companyId = getCurrentCompanyId(this.userId);
var courier = Couriers.findOne({ userId: this.userId });
var filterOptions = { companyId: courier.companyId, 'courier._id': courier._id, status: 'inprocess' };
console.log('applicationsMobileInprocess');
return Applications.find(filterOptions);
});
//Finish method
finishAppByCourier: function(appToFinish) {
check(this.userId, String);
check(appToFinish, String);
var userId = this.userId;
Applications.update(appToFinish,
{ $set:
{
factDeliverDateTime: new Date(),
status: 'finished'
}
});
var app = Applications.findOne(appToFinish);
if(Meteor.isServer){
Meteor.call('addToHistory', app, userId, 'courierFinishApp');
if(app.client.androidRegId)
Meteor.call('sendPushClientUser', app.client.androidRegId, 'Request is done!');
}
return {
success: true
};
ANDROID:
finishButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for(int i = 0;i<Login.activeList.size();i++){
if(Login.activeList.get(i).get(TAG_ID).equals(id)){
Login.mMeteor.call("finishAppByCourier",new Object[ {Login.activeList.get(i).get("documentID").toString()});
//Log.d("DocumentId", Login.activeList.get(i).get("documentID") + "");
}
}
Toast toast = Toast.makeText(getApplicationContext(),
"Request is finished", Toast.LENGTH_SHORT);
toast.show();
toast.setGravity(Gravity.CENTER, 0, 0);
            startActivity(intentBack);
        }
    });

//in OnCreate i subscribe on publications like this:
mMeteor.loginWithEmail(emailStr, passwordStr, new ResultListener() {
@Override
public void onSuccess(String s) {
                    String activeSub = mMeteor.subscribe("applicationsMobileInprocess");
                    String finishedSub = mMeteor.subscribe("applicationsMobileFinished");

                    startActivity(intent);
                }
                ...........

public void onDataAdded(String collectionName, String documentID, String newValuesJson) {
if(collectionName.equals("applications")){
   if(c.getString("status").equals("inprocess")){
      activeList.add(each_element_of_collection);
   }
   }else if(c.getString("status").equals("finished")){
      finishedList.add(each_element_of_collection);
   }
   ........

    if(ListOfElements.activeAdapter!=null){
        Log.d("ActiveAdapter", "activeChanged");
        ListOfElements.activeAdapter.notifyDataSetChanged();
    }

    if(FinishedListOfElements.finishedAdapter!=null){
        Log.d("FinishedAdapter", "finishedChanged");
        FinishedListOfElements.finishedAdapter.notifyDataSetChanged();
    }
}

}
@Override
public void onDataChanged(String collectionName, String documentID, String updatedValuesJson, String removedValuesJson) {
if(collectionName.equals("applications")){

    //i trace the changes in publications
    ........

    if(ListOfElements.activeAdapter!=null){
        Log.d("ActiveAdapter", "activeChanged");
        ListOfElements.activeAdapter.notifyDataSetChanged();
    }

    if(FinishedListOfElements.finishedAdapter!=null){
        Log.d("FinishedAdapter", "finishedChanged");
        FinishedListOfElements.finishedAdapter.notifyDataSetChanged();
    }
}

}
@Override
public void onDataRemoved(String collectionName, String documentID) {
if(collectionName.equals("applications")){
    for(int i = 0;i<activeList.size();i++){
        if(documentID.equals(activeList.get(i).get("documentID"))){
            activeList.remove(i);
        }
    }

    for(int j = 0;j<finishedList.size();j++){
        if(documentID.equals(finishedList.get(j).get("documentID"))){
            finishedList.remove(j);
        }
    }
}

if(ListOfElements.activeAdapter!=null){
    Log.d("ActiveAdapter", "activeRemoved");
    ListOfElements.activeAdapter.notifyDataSetChanged();
}

if(FinishedListOfElements.finishedAdapter!=null){
    Log.d("FinishedAdapter", "finishedRemoved");
    FinishedListOfElements.finishedAdapter.notifyDataSetChanged();
}

}
It works like: when you click to Finish button, element of listview(also in the same time it's the element of collection on the server) must change the status(in json "status":"finished") and move to finishedList from the activeList by the Meteor itself. But problem is when you click it, it changes the status and didn't call the removed sometimes. I notice that it depends on time. For example in 8.00 AM it works very fast and call the onchange and onremove methods correctly, but in 7.00 PM it just call onchange and change the status but onremoved is not calling. And i notice next thin. I have the local and main server. On local it works fine and correctly(i guess cause it's beside so internet connection will be perfect), but in my main server it works with these errors(server is working fine). I really hope that you can help me with these problems in short time.

can I see you "activeList" declaration I mean the class model and structure?

ArrayList<HashMap<String,String>> activeList;

This example is too complex to decide whether it's a bug in this library or in your code, I'm afraid.
Can you create a simple example that does what you want to test, only checks if the communication with this library is working (including onDataRemoved) and doesn't have all the business logic that your existing example has?
And please tell us if you're working on an emulator or on a real device and if you're hosting the app on *.meteorapp.com or somewhere else.
Thank you!

Closing due to inactivity and because the example is too complex


Wallet metadata in Wallet Instance Attestation

In https://github.com/WalletInteroperabilityLab/eudi-wif/blob/versione-corrente/docs/en/wallet-instance-attestation.rst there is a set of claims that describes metadata that could be useful when the Wallet interacts with a Verifier.
That set of metadata is of no usage in the context where the Wallet interacts with a Credential Issuer. Here another set of claims could be useful.
To me this means that the present text can not stand. We should either remove these claims completely or accept that a wallet may have WIAs of different kinds. One when it acts as an OIDC RP communicating with a Credential Issuer and another when it acts as an OIDC OP when interacting with a Verifier. If we choose the later path we have to define two sets of metadata schemas.

this was my first assumption and in italy we agreed that we should have multiple WA for different scopes
this is something not defined yet in the EUDI Wallet
the direction we're taking, even if still under discussion, is to have a WA with the sole key attestation to be used for both issuance and presentation and the wallet instance metadata would be provided to the RP using the Advanced Flow.

The whole flow of attestations needs to be looked at.
The wallet instance needs to provide attestations to the wallet provider to get an instance attestation.

an attestation of something like Safety Net or its equivalent to show package integrity, at least for native implementations.
An attestation for the proof key is used to present the attestation.  It might be the PAR signing key, depending on the flow.
an attestation over the public keys that will be included in the PIDS.

In 2, the provider should know that the proof key the wallet will use to get the PIDS is in hardware or the chain of trust is broken.
There may be a gap in OID4VCI in 3.  OID4VCI assumes that any key the wallet can provide and sign a nonce with could be used to bind the issued PID to the wallet.  I think the wallet provider needs to indicate that the public key to be bound is OK (secured in HW).   There is a built-in assumption that if the wallet is verified, it will manage all its keys properly.  That that a more difficult assumption to make about a web wallet.


[T4A3][F09-B3] Chen Tiankai

Ready for review.

Good job!!

@TiankaiChen Some comments added. Please close the PR after reading comments.


Version of Stream::merge() without Both?

I have an application where I'd like to receive events from several Streams, but I only want to receive one event at a time.  Stream::merge() is nearly right, but instead of receiving Both(a,b) if both sub-streams are ready, I would prefer to just receive one of the two, and leave the other to the next poll.
So my proposal would be to add a new method like merge (for lack of a better name, mesh), which returns something just like stream::Merge (say Mesh), which returned a MeshedItem which lacks the Both variant.
One complication is that you need to have a policy for which one you return; the simplest would be to favour the first (but risk never getting to the second if it's busy); otherwise a round robin policy might be better (but less ideal if you mesh several together in pairs).
In my application I want to expose a blocking "get next event" API to the client, where the events would be things like keypresses, timers, and signals; my current idea is to mesh the event sources together as above and block on core.run(meshed.into_future()).  Happy to hear it's a dumb idea and there's a better way to do it.  :-)

One way to do this is to use flatten. That is,
enum Event {
    Key(Key),
    Button(Button)
}
stream_mouse.merge(stream_keyboard).map(|event| {
    let (first, second) = match event {
        Both(button, key) => (Event::Button(button), Some(Event::Key(key)))
        First(button) => (Event::Button(button), None),
        Second(key) => (Event::Key(key), None),
    };
    stream::iter(iter::once(first).chain(second).map(Ok))
}).flatten()

However, I think this would be better served with a Stream::select method (like the one on Future). Basically merge but:

Only accepts one type.
Has round-robin polling.

That way you could write:
stream_mouse.map(Event::Button).select(stream_keyboard.map(Event::Key))

@Stebalien your idea sounds great to me, and I think that'd solve @jugglerchris's use case as well! @jugglerchris what do you think of that?

Hi,
A select as described sounds good to me, and does solve my problem.
The one niggle I'd have with just a 2-way select is that the round robin doesn't compose: a.select(b.select(c)) becomes "unfair" and would produce a,b,a,c,a,b,a,c if all three are ready. It'd be nice to be able to solve this fairly somehow.
Perhaps all it needs is a new method on the Select struct, so you'd do:
a.select(b).also_select(c)

Chris

@jugglerchris hm true yeah but that'd be the case no matter what for what you were thinking above as well, right?

@jugglerchris we could also add a select_all method.

@alexcrichton Yes, the select is at least as good as my idea. :-)

I've posted a PR for this in https://github.com/alexcrichton/futures-rs/pull/241

Wow, thanks for implementing this so quickly!

I've tried it out, and so far so good, thanks!


gulp.watch does not emit deletion events for directories or their files on directory deletion

Tested in gulp 4.0 and gulp 3.9.1.
When a watched directory is deleted, no events are fired for directories or their files.
With the following initial folder structure:
test
├── dir
│   └── foo
└── test

These actions are executed manually:

Create folder test/dir2 (should emit addDir - test/dir2)
Create file test/dir2/foo (should emit add - test/dir2/foo)
Create file test/dir2/bar (should emit add - test/dir2/bar)
Delete file test/dir2/bar (should emit unlink - test/dir2/bar)
Delete folder test/dir2 (should emit unlinkDir - test/dir2 and/or unlink test/dir2/foo)
Delete folder test/dir (should emit unlinkDir - test/dir and/or unlink test/dir/foo)
Delete file test/test (should emit unlink - test/test)

As can be seen below, the watch listener is never informed of the deletion of test/dir2 or test/dir, nor that of the foo file in either of them.

gulpfile.js (gulp 4.0):
var gulp = require("gulp");
gulp.task("test", function(){
  return gulp.watch("test/**/*")
    .on("all", function(event, path) {
      console.log(event+" - "+path);
    });
});

Expected output:
addDir - test/dir2
add - test/dir2/foo
add - test/dir2/bar
unlink - test/dir2/bar
unlinkDir - test/dir2    (and/or unlink test/dir2/foo)
unlinkDir - test/dir     (and/or unlink test/dir/foo)
unlink - test/test

Observed output:
addDir - test/dir2
add - test/dir2/foo
add - test/dir2/bar
unlink - test/dir2/bar
unlink - test/test

I believe delete events are really hard to listen to.  This would be something for you to research in relation to gaze and chokidar.


feat: update checking functionality to support checking if user exists in one of multiple teams

Feature:
Allow user checking to check if user exists in one of multiple teams supplied in the input

@binayabaral Thank you for your contribution. I've made a minor tweak (trim individual team names in case there are spaces), fix the action.yml team parameter description and added an integration test


Make 'explain' explain show and hide commands

Seems that explain does not mention tags being hidden. Might be useful.
Originally posted by @ksdavidc in https://github.com/obsidian-tasks-group/obsidian-tasks/discussions/848#discussioncomment-6343613

Thanks. Another time it would be helpful if you could use the Feature Request template.

This will do - I've edited the title to make it a more general request.
Thanks again.

Related:
Make 'explain' explain group commands
Make 'explain' explain sort commands
Make 'explain' explain show comments


GObject-Object.lua:100: bad argument #8 to 'object_new'

Hi,
So I was having this issue:
lua5.2: .../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:100: bad argument #8 to 'object_new' (string expected, got userdata)
stack traceback:
	[C]: in function 'object_new'
	.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:100: in function '_construct'
	.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:216: in function <.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:215>
	(...tail calls...)
	test.lua:8: in main chunk
	[C]: in ?

And was trying to figure it out when I decided to go through the bug reports here on github, and this latest issue provides a good test case:
https://github.com/pavouk/lgi/issues/166
Copy+paste that code into test.lua, run it, and get the result above.
$ apt-cache show luarocks | grep Version
Version: 2.4.2+dfsg-1
$ apt-cache show gobject-introspection | grep Version
Version: 1.53.2-4
$ apt-cache show libglib2.0-0 | grep Version
Version: 2.53.4-3

I seem to be missing the point. If you are saying that you run into #166, why are you opening a new issue for it?

Ah, yes, I should probably have been more clear.
This is not the same issue, but #166 has a tiny testcase that works for this as well.
Here is a even smaller test case, based on the one from #166.
#! /usr/bin/env lua
local lgi = require 'lgi'
local Gtk = lgi.Gtk
local w = Gtk.Window {}
Gtk.main()

Okay, what error message do you get when running that example? (I'm curious about the line numbers in the stack trace)
Also, could you try running with gobject-introspection from testing? Your version seems to be the one from Debian unstable and this seems like a likely culpit for the breakage.

Certainly, the error is obviously the same as in comment 1, but the line numbers in this stack are from the 5-line example given in comment 3.
Also it now says that the error is "bad argument #4" instead of #8, probably because the offending line changed from Gtk.Button { label = "click me!", id = "btn" } to local w = Gtk.Window {}
$ lua test.lua
lua: .../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:100: bad argument #4 to 'object_new' (table expected, got nil)
stack traceback:
	[C]: in function 'object_new'
	.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:100: in function '_construct'
	.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:216: in function <.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:215>
	(...tail calls...)
	test.lua:4: in main chunk
	[C]: in ?

So I downgraded gobject-introspection and libgirepository-1.0-1 to 1.50.0-2 from https://packages.debian.org/source/buster/gobject-introspection and the results seem to be the same. I did not downgrade any other packages from that source (for example libgirepository1.0-dev), and the only thing I did after dpkg -i completed was opening a new tty to get a somewhat fresh environment, then I ran it again:
$ lua test.lua
lua: .../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:100: bad argument #4 to 'object_new' (table expected, got nil)
stack traceback:
	[C]: in function 'object_new'
	.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:100: in function '_construct'
	.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:216: in function <.../.luarocks/share/lua/5.2/lgi/override/GObject-Object.lua:215>
	(...tail calls...)
	test.lua:4: in main chunk
	[C]: in ?

Right, so I thought about it a second time, and then I downgraded https://packages.debian.org/buster/gir1.2-glib-2.0 from 1.53.2-4 to 1.50.0-2, and now there is no error.

https://developer.gnome.org/gobject/2.53/gobject-The-Base-Object-Type.html#g-object-newv

Ah, they changed the API. Great.
Possible patch (completely untested):
diff --git a/lgi/override/GObject-Object.lua b/lgi/override/GObject-Object.lua
index bb59883..83370fa 100644
--- a/lgi/override/GObject-Object.lua
+++ b/lgi/override/GObject-Object.lua
@@ -67,7 +67,7 @@ function Object:_construct(gtype, param, owns)
    if object then return object end

    -- Process 'args' table, separate properties from other fields.
-   local parameters, others, safe = {}, {}, {}
+   local names, values, parameters, others, safe = {}, {}, {}
    for name, arg in pairs(param or {}) do
       if type(name) == 'string' then
         local argtype = self[name]
@@ -90,6 +90,9 @@ function Object:_construct(gtype, param, owns)
            local marshaller = Value.find_marshaller(gtype, argtype.typeinfo)
            marshaller(value, nil, arg)
            parameters[#parameters + 1] = parameter
+
+           names[#names + 1] = name
+           values[#values] = parameter
         else
            others[name] = arg
         end
@@ -97,7 +100,7 @@ function Object:_construct(gtype, param, owns)
    end

    -- Create the object.
-   object = object_new(gtype, parameters)
+   object = object_new(gtype, names, values)

    -- Perform initialization on interfaces.
    if next(self._implements) then

Instead of object = object_new(gtype, names, values) possible it needs to be object = object_new(gtype, #names, names, values). I'm not sure about the magic that adds array lengths here.
Alternatively, the following might also work:
diff --git a/lgi/override/GObject-Object.lua b/lgi/override/GObject-Object.lua
index bb59883..4a8db39 100644
--- a/lgi/override/GObject-Object.lua
+++ b/lgi/override/GObject-Object.lua
@@ -39,7 +39,7 @@ end
 -- to initialize.
 local parameter_repo = repo.GObject.Parameter
 local object_new = gi.GObject.Object.methods.new
-if object_new then
+if false and object_new then
    object_new = core.callable.new(object_new)
 else
    -- Unfortunately, older GI (<1.30) does not export g_object_newv()

Since I do not have much clue about GI, I'll leave this to @pavouk.

And one last possible patch (I see that the rename of newv to new is gone, so it might be okay to just continue using newv for the time being):
diff --git a/lgi/override/GObject-Object.lua b/lgi/override/GObject-Object.lua
index bb59883..9227ef7 100644
--- a/lgi/override/GObject-Object.lua
+++ b/lgi/override/GObject-Object.lua
@@ -38,7 +38,7 @@ end
 -- Object constructor, 'param' contains table _with properties/signals
 -- to initialize.
 local parameter_repo = repo.GObject.Parameter
-local object_new = gi.GObject.Object.methods.new
+local object_new = gi.GObject.Object.methods.newv or gi.GObject.Object.methods.new
 if object_new then
    object_new = core.callable.new(object_new)
 else

And one last possible patch

This last patch seems to get things working again, by itself.
Thank you!

Just bumping that last patch, would be nice to get it in a realize before GLib 2.54 is out.

hi!
with 0.9.2 + Glib2 2.64.5 I get:

Gio.DBusObjectManagerClient.new_sync(
Gio.bus_get_sync(Gio.BusType.SYSTEM), "org.bluez", "/")

stdin:1: bad argument #-1 to 'new_sync' (number expected, got nil)
stack traceback:
[C]: in field 'new_sync'
stdin:1: in main chunk
[C]: in ?
Is this again the API breakage or something?

Why do you think so? Did that ever work? According to the API docs, the second argument should be some flags. Adding a 0 argument here works (thanks to all those nullable arguments...):
lua -e 'lgi = require("lgi"); gio = lgi.Gio; gio.DBusObjectManagerClient.new_sync(gio.bus_get_sync(gio.BusType.SYSTEM), 0, "org.bluez", "/")'

my fault. "Deep night effect". Thanks for your help!


Fix packaging

Remove unneeded packages from requirements.txt (this file is meant for third party packages from PyPI)
setup.py: Fix file name

Closing in favor of #6


Multiple stack trace analysis

One of the reasons that many JVM developers are still stuck to IBM Thread and Monitor Dump Analyze for Java is that it can compare multiple thread dumps. Would it be possible to add such a feature to JStackFX as well?

Hi,
Thank you for your interest in JStackFX. Analysing multiple thread dumps is currently the feature I'm working on and should be available in a further release.


Crash with +[RLMRealm realmWithConfiguration:confinedTo:error:] + 3608 (RLMRealm.mm:433)

How frequently does the bug occur?
Sometimes
Description
After upgrading the compilation to Xcode Version 16.0 (16A242d), I noticed that a couple of my app user is reporting the following crash point from realmDB (10.45.2).
I made very incremental/cautious changes in the previous app release and just upgraded Xcode alone. And this happened with a very small chance but due to the huge installation base, the problem is still collected in the crash report. I have a free threads using the ReamDB concurrently but with different table. Not sure if this would increase the chance the bug is reported.
Stacktrace & log output
0   Realm                         	0x000000010545c624 realm::Exception::what() const + 128
1   Realm                         	0x00000001052e2884 makeError(realm::Exception const&) + 124 (RLMError.mm:188)
2   Realm                         	0x00000001053d8a94 RLMRealmTranslateException(NSError* __autoreleasing*) + 80 (RLMRealm.mm:170)
3   Realm                         	0x00000001053da570 +[RLMRealm realmWithConfiguration:confinedTo:error:] + 3608 (RLMRealm.mm:433)
4   Realm                         	0x00000001053d96dc +[RLMRealm realmWithConfiguration:queue:error:] + 88 (RLMRealm.mm:395)
5   RealmSwift                    	0x0000000105cd109c specialized @nonobjc RLMRealm.__allocating_init(configuration:queue:) + 40 (/<compiler-generated>:0)
6   RealmSwift                    	0x0000000105cd109c @nonobjc RLMRealm.__allocating_init(configuration:queue:) + 40 (/<compiler-generated>:0)
7   RealmSwift                    	0x0000000105cd109c Realm.init(queue:) + 140 (Realm.swift:78)
... Aboove is my source code that tries to use Realm.

Can you reproduce the bug?
Sometimes
Reproduction Steps
No specific steps. As I mentioned, my app have a few threads accessing RealmDB at the same time, but to different databases. Also this issue seemed to only happen after I upgraded the Xcode to Version 16.0 (16A242d)has
Version
10.45.2
What Atlas Services are you using?
Local Database only
Are you using encryption?
No
Platform OS and version(s)
iOS 18.1, iOS 18.0, iOS 17.7, iOS 17.5, iOS 17.4...
Build environment
Xcode version: Xcode Version 16.0 (16A242d)
Dependency manager and version: Cocoapod 1.14.3

Is there any updates on this issue? Also to supplement more information -

The error crashed with:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Subtype: KERN_PROTECTION_FAILURE at XXXXX

So I assume there are some bad memory allocation happened in the SDK.

I checked many core dumps in the app crashes, and found that many of the other threads are doing photo requests (I am doing a photo related App) with the following stack.

0   libsystem_kernel.dylib        	0x00000001db9d1424 kevent_id + 8
1   libdispatch.dylib             	0x000000019ac421bc _dispatch_event_loop_wait_for_ownership + 436 (event_kevent.c:2232)
2   libdispatch.dylib             	0x000000019ac2e594 __DISPATCH_WAIT_FOR_QUEUE__ + 340 (queue.c:1700)
3   libdispatch.dylib             	0x000000019ac2e15c _dispatch_sync_f_slow + 148 (queue.c:1784)
4   CoreData                      	0x000000019aee015c -[NSManagedObjectContext performBlockAndWait:] + 264 (NSManagedObjectContext.m:4102)
5   PhotoLibraryServices          	0x00000001aa9e01f4 -[PLManagedObjectContext _directPerformBlockAndWait:] + 144 (PLManagedObjectContext.m:411)
6   PhotoLibraryServices          	0x00000001aa9e0148 -[PLManagedObjectContext performBlockAndWait:] + 196 (PLManagedObjectContext.m:777)

Unsure if this might cause any race conditions / resource contentions.
Hope these information would be useful, and I am looking for any quick resolution / workaround to stabilize this app. Thanks in advance!

I know you shouldn't, but for me it helped to make sure only one thread at a time is accessing my realm.

Interesting - I tried to upgrade Realm to v20.0.0 and pushed it to production. Will see if the huge user base can reproduce this issue. From https://github.com/realm/realm-swift/issues/8692, it seemed the issue was solved by upgrading Realm to 10.54.0. Not sure if the fix was included in 20.0.0, which is just one version before 10.54.0.

There shouldn't be any functional differences between v10.54.0 and v20.0.0 other than the sync functionality not being present.