Fix invalid unit names in metadata files

What does this PR do?
Fixes invalid unit names in each integration's metric metadata.
Motivation
New changes to metric documentation would not be built if their metadata contains invalid unit names.
Reference for allowed metrics unit names: https://docs.datadoghq.com/developers/metrics/#units
Review checklist

[ ] PR has a meaningful title or PR has the no-changelog label attached
[ ] Feature or bugfix has tests
[ ] Git history is clean
[ ] If PR impacts documentation, docs team has been notified or an issue has been opened on the documentation repo

Additional Notes
I've removed several invalid unit names, what synonyms can they be replaced with?

Could we break this up into smaller prs so its easier to review and merge?
Also it'd be helpful to get a list of unit names so we can work on those synonyms to replace them.

Here is a list of all the invalid units that I removed (having no trivial synonym):
active_directory:
    properties:
        11: active_directory.dra.inbound.properties.applied_persec,gauge,,,second,The number of changes (per second) to object properties that are applied through inbound replication as a result of reconciliation logic.,-1,active_directory,ad dra properties applied
        12: active_directory.dra.inbound.properties.filtered_persec,gauge,,,second,The number of changes (per second) to object properties received during the replication that are already made.,-1,active_directory,ad dra properties filtered
        13: active_directory.dra.inbound.properties.total_persec,gauge,,,second,The total number of changes (per second) to object properties received from replication partners.,-1,active_directory,ad dra properties total
        22: active_directory.dra.outbound.properties.persec,gauge,,,second,"The number of properties sent per second. This counter tells you whether a source server is returning objects or not. Sometimes, the server might stop working correctly and not return objects quickly or at all.",-1,active_directory,ad dra outbound properties
    values:
        15: active_directory.dra.inbound.values.total_persec,gauge,,,second,"The total number of values of object properties received (per second) from replication partners. Each inbound object has one or more properties, and each property has zero or more values. A value of zero indicates that the property is to be removed.",-1,active_directory,ad dra inbound total
        24: active_directory.dra.outbound.values.total_persec,gauge,,,second,"The total number of values of object properties sent (per second), to replication partners.",-1,active_directory,ad dra outbound values
    synchronizations:
        25: active_directory.dra.replication.pending_synchronizations,gauge,,,,"The number of directory synchronizations that are queued for this server that are not yet processed. This counter helps in determining replication backlog — the larger the number, the larger the backlog.",-1,active_directory,ad dra replication syncs
    binds:
        30: active_directory.ldap.successful_binds_persec,gauge,,,second,The number LDAP bindings (per second) that occurred successfully.,-1,active_directory,ad ldap binds
    searches:
        active_directory.ldap.searches_persec,gauge,,,second,The number of search operations per second performed by LDAP clients.,-1,active_directory,ad ldap searches

consul:
    peer:
        19: consul.peers,gauge,,,,Number of peers in the peer set,0,consul,peer

coredns:
    response code:
        2: coredns.response_code_count,gauge,,,,number of responses per zone and rcode,1,coredns,response code
    request type:
        7: coredns.request_type_count,gauge,,,,counter of queries per zone and type,1,coredns,request type

couchbase:
    badval:
        17: couchbase.by_bucket.cas_badval,gauge,,,,Compare and Swap bad values,-1,couchbase,cas badval
    backoff:
        49: couchbase.by_bucket.ep_dcp_fts_backoff,gauge,,,,Number of backoffs for fts DCP connections,-1,couchbase,dcp fts backoff
        55: couchbase.by_bucket.ep_dcp_2i_backoff,gauge,,,,Number of backoffs for indexes DCP connections,-1,couchbase,dcp indexes backoff
        61: couchbase.by_bucket.ep_dcp_other_backoff,gauge,,,,Number of backoffs for other DCP connections,-1,couchbase,dcp other backoff
        67: couchbase.by_bucket.ep_dcp_replica_backoff,gauge,,,,Number of backoffs for replica DCP connections,-1,couchbase,dcp replica backoff
        73: couchbase.by_bucket.ep_dcp_views_backoff,gauge,,,,Number of backoffs for views DCP connections,-1,couchbase,dcp views backoff
        79: couchbase.by_bucket.ep_dcp_xdcr_backoff,gauge,,,,Number of backoffs for xdcr DCP connections,-1,couchbase,dcp xdcr backoff
    producer:
        53: couchbase.by_bucket.ep_dcp_xdcr_backoff,gauge,,,,Number of backoffs for xdcr DCP connections,-1,couchbase,dcp xdcr backoff
        59: couchbase.by_bucket.ep_dcp_2i_producer_count,gauge,,,,Number of indexes producers,0,couchbase,dcp indexes producer
        65: couchbase.by_bucket.ep_dcp_other_producer_count,gauge,,,,Number of other producers,0,couchbase,dcp other producer
        71: couchbase.by_bucket.ep_dcp_replica_producer_count,gauge,,,,Number of replica producers,0,couchbase,dcp replica producer
        77: couchbase.by_bucket.ep_dcp_views_producer_count,gauge,,,,Number of views producers,0,couchbase,dcp views producer
        83: couchbase.by_bucket.ep_dcp_xdcr_producer_count,gauge,,,,Number of xdcr producers,0,couchbase,dcp xdcr producer

exchange_server:
    aquires:
        18: exchange.netlogon.semaphore_acquires,count,,,,"The total number of times that the semaphore has been obtained over the lifetime of the security channel connection, or since system startup for _Total.",-1,exchange_server,sem aquires
    copies:
        29: exchange.activemanager.database_mounted,gauge,,,,Shows the number of active database copies on the server.,-1,exchange_server,active database mounts

nginx:
    slot:
        93: nginx.slab.slots.free,gauge,,,,The current number of free memory slots,-1,nginx,slab slots free
        96: nginx.slab.slots.used,gauge,,,,The current number of used memory slots,-1,nginx,slab slots used

 metadata file validations


Add declarative support for required parameters and properties

Add a NonNull annotation to org.httprpc.kilo that can be associated with service method parameters and bean properties.
The annotation should be defined in kilo-server, since it would be evaluated by WebService. NonNull is preferable to the following alternatives for the reasons outlined below:

Nullable - would require code to opt in to "optional" behavior vs. opting in to "required" (thus making existing un-annotated code implicitly required, which may be a semantic change)
Optional - same as above, plus conflicts with existing Optional type
NotNull from Bean Validation framework - would necessitate an undesirable external dependency
Required - same meaning, but NonNull appears to be more common and may be more intuitive

As part of this change, generated documentation will include a new "required" property that will reflect the presence (or lack) of the annotation. A "?" character will be appended to all nullable (non-required) types in the generated HTML, which mirrors the optional syntax used by other programming languages.
While this feature could be used to automate some rudimentary validation, the primary objective is not to provide a validation framework, but to eliminate boilerplate null checks and better support client languages that natively support optional types.

Argument validation can be performed immediately before the method is invoked, and body validation can be performed in getBody(). In both cases, a validation failure can throw IllegalArgumentException, triggering an HTTP 403 response.

Note that "boilerplate" null checks may still be required if service methods are invoked directly (e.g. by other services).

May go with Require instead of NonNull since it could be applied to primitive values, which are inherently not nullable. Require may be preferable to Required since it is consistent with Ignore, Override, etc.

This is done.


Vs15.8

Integrate vs15.8 -> VSTS PR build experimental branch

I'll just do this manually, never mind :)


How are AP Payments Created

Hello,
I am not seeing a function for creating AP Payments.  Am I missing something?
Thanks,
Mike

I am seeing the APPaymentRequest now.  Looks like that is what I am needing.


chore(main): release 0.9.5

:robot: I have created a release beep boop
0.9.5 (2024-09-16)
Bug Fixes

fix analytics (951209b)

This PR was generated with Release Please. See documentation.

:robot: Created releases:

v0.9.5
:sunflower:


Rl integration

added test cases for ST access token, and LT access token.  return from POST should be 201, and made utils.popToke.GenerateToken by reference, keeping the fields beyond the method scope.

Another pull request will be issued.


Adding telegraf config for Marvell

great work

to pass DCO, you need to add --signoff option in git
to pass Commitlint , you need to start your message from: feat: or fix: or docs: and so on...


Use --trainer-snapshot option of Tox21

This PR fixes #67 by using a snapshot specified by --trainer-snapshot if it is not empty. I also change the testing scripts for examples to check this option.

snapshot=ls ${out_dir}/snapshot_iter_*  # Assume there is only one snapshot file.

https://unix.stackexchange.com/questions/21471/how-do-i-limit-the-number-of-files-printed-by-ls
Maybe we can change this to
snapshot=ls ${out_dir}/snapshot_iter_* | head -1  # Assume there is at least one snapshot file.

Thanks, I changed as you suggest.

Did you test this code? If it runs ok, please merge it.

Yes, I ran the test scripts. They completed without errors. By the way can I merge by myself? It is OK to do so as the reviewer (you) agreed. But I'm just curious.

PR submitter must get approve from others, but once you get approved it is ok to merge by yourself after test completed without errors.


How to define new distributions?

I would like to define new distributions using scipy.stats. Such a distribution would have a set of parameters, and one could evaluate its PDF, CDF, create random variates etc.
For continuous distributions, there is a short description under "Subclassing" in the documentation of rv_continuous. It says one should subclass rv_continuous, and as a minimum redefine _pdf and _cdf, plus possibly a list of others. The description alludes to a lot of things that I don't understand, or understand only very superficially (e.g. "frozen distributions").
I guess one could understand this description if there were some kind of general documentation of the design of scipy.stats, but I wasn't able to find it.
Questions:

Can I redefine __init__, and if yes, how should I call super().__init__?

In case I am not supposed to redefine __init__, how do I pass parameters to my subclass?

What are the constraints on the signatures of the methods to be redefined? For example, do I have to provide for distribution parameters to be passed, even though I just want to define them upon instantiation?

Do I have to support loc and scale, though I don't want to translate and scale my distribution? The phrase "re-defining at least the _pdf or the _cdf method (normalized to location 0 and scale 1)" seems to suggest that these parameters are automatically taken care of?

If I implement _rvs, can I assume that self.random_state is defined? Should I implement a parameter random_state myself, or is that taken care of by rv_continuous.rvs?

How does rvs pass the number of samples (size) to _rvs?

How are the interface methods (e.g. ppf) based on the methods I redefine? If I have performance problems with some interface method, which internal method should I additionally redefine? A dependency graph with some indication of performance bottlenecks and loss of precision would be useful.

A note on shapes: subclasses need not specify them explicitly. In this case, shapes will be automatically deduced from the signatures of the overridden methods (pdf, cdf etc). If, for some reason, you prefer to avoid relying on introspection, you can specify shapes explicitly as an argument to the instance constructor.

I have only the faintest idea what this means. How exactly are shapes "automatically deduced from the signatures of the overridden methods"? How can I "specify shapes explicitly as an argument to the instance constructor" if __init__ is not in the list of methods to be redefined?

These are just the questions I came up with at my current state of understanding, I'm sure if I understood more I had much more to ask.

I now realize that the documentation does not mention __init__ as one of the methods that can be overridden. I guess the question then becomes, how do I pass parameters to my new class upon instantiation?
And if I can override __init__, of course I have to call super().__init__. The following additional line at the beginning of __init__ appears to fix my problem:
super().__init__(self)

However, stats.rv_continuous.__init__ has many parameters. Do I have to / should I set some of them? The documentation is sparse:
>> stats.rv_continuous.__init__?
Signature:
stats.rv_continuous.__init__(
    self,
    momtype=1,
    a=None,
    b=None,
    xtol=1e-14,
    badvalue=None,
    name=None,
    longname=None,
    shapes=None,
    extradoc=None,
    seed=None,
)
Docstring: Initialize self.  See help(type(self)) for accurate signature.
File:      ~/.conda/envs/std/lib/python3.8/site-packages/scipy/stats/_distn_infrastructure.py
Type:      function

How does rvs pass the number of samples (size) to _rvs?

By poking around I found that apparently this is done via an instance variable self._size? Why would you do it like this (contrary to everything I pretend to know about OOP)? And why isn't it documented anywhere?

Hi @allefeld . I think you are mentioning based on the basic help from http://scipy.github.io/devdocs/tutorial/stats.html
There is also SciPy contributor guide that has a bit more details about the machinery how we add things http://scipy.github.io/devdocs/dev/contributor/adding_new.html#adding-a-new-statistics-distribution
However most of your questions if not all are elaborated in the docstring of rv_continuous http://scipy.github.io/devdocs/generated/scipy.stats.rv_continuous.html#scipy.stats.rv_continuous
The best way to get used to it is to see the implementations of different distributions in the source code.

Oops nevermind I just saw you edited the body of the issue

@ilayn, yes, sorry, I made a big mess at first and then tried to create a proper issue.
I would really appreciate some explanation. Thanks for pointing me to the contributor guide! But just by skimming quickly I think that there are still several of my points not covered.

Yes, there is some back and forth needed in the distribution docs but if you go through the methods of rv_continuous, for example fit would give a bit more info about the shapes, you can familiarize yourself. I am trying not to comment since our domain residents would probably be more helpful, and I would probably confuse you more since I usually butcher my way out when I'm using any statistical tool.
Maybe you can give a concrete example of a distribution you want to implement so people can explain more carefully? Who knows maybe it would be a candidate to add in the menu we have.

Best might be to look at some recent PRs that added new distribution. (I don't remember which right now.)
about _size in rvs: this is old behavior #11394 and currently under change
main point about the structure:
scipy stats distributions are or should be stateless, i.e. each method call need all parameters that define the distribution. There is only one instance of a distribution class, and having statefull attributes causes problems in spilling over to unrelated cases.
The disadvantage is that we cannot store the results of intermediate computations which would speed up the method calls.
subclasses should only redefine the methods that start with underline, e.g. _pdf, (and maybe fit). The inherited pdf, ppf, ... handle loc-scale, broad casting, domain checking, and have generic version for methods that are not defined in the specific distribution class.

I went through my email and got confused about the mixture distribution case.
If you are NOT writing a new distribution class for scipy.stats and only want to use it for your own usecase or library, then there is no restriction on not having statefull attributes.
But then, each instance of the class will be specific to the arguments or attributes define in __init__, and you shouldn't create a single instance as does scipy.stats.distributions
two examples from statsmodels
zero inflated poisson follows the scipy.stats convention, it hard codes the distribution, and uses all parameter as method arguments, no __init__
(aside rvs is slow because it doesn't define _rvs and uses the slow generic method.)
https://github.com/statsmodels/statsmodels/blob/master/statsmodels/distributions/discrete.py#L45
ancient code of mine that I haven't looked at in a long time:
(The code has some minimal unit tests, so it should still be working after 10 to 12 years)
Define distribution and other things in __init__ which don't show up as method arguments
https://github.com/statsmodels/statsmodels/blob/master/statsmodels/sandbox/distributions/transformed.py#L55
If we want a single instance, then it has to define all extra __init__ arguments, and is then specific to that case. The remaining parameters for the distribution are don't define a state through attributes
https://github.com/statsmodels/statsmodels/blob/master/statsmodels/sandbox/distributions/transformed.py#L115

@josef-pkt, thanks for the pointers!
I wasn't aware that there are only single instances of distribution classes. (Is this documented anywhere?) I admit the fact that the distribution parameters can or should be included in each method call already indicates that.
What I don't understand is why you chose to do it this way? You already mentioned performance issues, but even apart from that, from my (maybe naive) perspective it appears to be just plain illogical.
IMHO the OOP logic maps nicely on the logic of distributions. A parametrized family of distributions =  a class, a specific distribution with fixed parameters = an instance. If one family is a special case of another, this can be modeled by inheritance. There can be different instances with the same parameters, they model i.i.d. RVs.
I also don't understand why you include location and scale parameters for every distribution. In some cases that makes sense, e.g. relative frequencies are scaled-binomial, but in many others it doesn't. Apparently it also makes it hard to specify parameters for some distributions, see A rant on scipy.stats. This problem has even given rise to a wrapper library, distcan. I would have implemented optional translation and scaling by a wrapper class, e.g. LocationScale(dist, loc, scale), where dist can be an arbitrary other distribution.
I realize criticism is cheap and you put a lot of work into this. But I have to say these for me strange design decisions have already impeded my use of the library, and right now make it very hard to build on it.

As for my own implementation, immediately it is only meant for my own use. Here is my current version, and it seems to work fine so far:
class Mixture (stats.rv_continuous):
    "Mixture distribution"

    def __init__(self, distributions, probabilities):
        super().__init__(self)
        self.dists = distributions
        probabilities = np.array(probabilities)
        self.probs = probabilities / sum(probabilities)

    def _pdf(self, x):
        pdf = 0
        for dist, prob in zip(self.dists, self.probs):
            pdf = pdf + prob * dist.pdf(x)
        return pdf

    def _cdf(self, x):
        cdf = 0
        for dist, prob in zip(self.dists, self.probs):
            cdf = cdf + prob * dist.cdf(x)
        return cdf

    def _rvs(self):
        N = np.prod(self._size)
        ns = np.random.multinomial(N, self.probs)
        samples = []
        for dist, n in zip(self.dists, ns):
            samples.append(dist.rvs(size=n))
        samples = np.hstack(samples)
        samples = np.random.permutation(samples).reshape(self._size)
        return samples

Wow, I had never heard of distcan. That looks potentially very useful. I don't think there's been a consistent proposal before on folding something like that into scipy.stats.

I'm not sure that this is interesting to you, but just in case, here is an example of a tiny class hierarchy modeling distributions that I defined (outside of the scipy.stats framework, but with a similar interface). I think it demonstrates the advantage of passing parameters to __init__. The point of the Empirical class is that its CDF is the ECDF, and it can be used to create bootstrap replications.
Just to be clear: What I do like about your approach is that you have inherited default implementations based e.g. on numerical integration, which use private methods if present.
import numpy as np

class Discrete:
    """
    discrete distribution
    """

    def __init__(self, values, weights=None):
        # input checking and normalization
        values = np.array(values).flatten()
        values, index, counts = np.unique(values, return_index=True, return_counts=True)
        if np.any(counts > 1):
            raise ValueError('values must be unique')
        if weights is not None:
            weights = np.array(weights).flatten()
            weights = weights[index]
            if len(weights) != len(values):
                raise ValueError('number of weights must match number of values')
        else:
            weights = np.ones(len(values))
        # set state
        self.xk = values
        self.pk = weights / sum(weights)
        self.Pk = np.cumsum(self.pk)
        self.Pk0 = np.hstack((0, self.Pk)) # for CDF lookup

    def pmf(self, x, tol=0.0):
        """
        probability mass function
        """
        # normalization
        x = np.array(x)
        shape = x.shape
        x = x.flatten()
        # compute
        e = np.abs(x - self.xk[:, np.newaxis])
        ind = np.argmin(e, axis=0)
        p = self.pk[ind]
        eMin = e[ind, np.arange(e.shape[1])]
        p[eMin > tol] = 0.0
        # back into shape
        p = np.reshape(p, shape)
        return p

    def cdf(self, x):
        """
        cumulative distribution function
        """
        # normalization
        x = np.array(x)
        shape = x.shape
        x = x.flatten()
        # compute
        ind = np.sum(self.xk[:, np.newaxis] <= x, axis=0)
        P = self.Pk0[ind]
        # back into shape
        P = np.reshape(P, shape)
        return P

    def __call__(self, x):
        """
        F(x) is a shortcut for F.cdf(x).
        """
        return self.cdf(x)

    def rvs(self, size=None, rng=None):
        rng = np.random.default_rng(rng)
        return rng.choice(self.xk, p=self.pk, size=size)

    def support(self):
        return self.xk

    def __repr__(self):
        return f'Discrete({repr(self.xk)}, {repr(self.pk)})'

class Empirical(Discrete):
    """
    empirical distribution
    """

    def __init__(self, sample):
        (xu, cu) = np.unique(sample, return_counts=True)
        super().__init__(xu, cu)
        self.n = len(sample)

    def bootstrap_sample(self, N=1, rng=None):
        rng = np.random.default_rng(rng)
        if N == 1:
            return self.rvs(size=self.n, rng=rng)
        else:
            return self.rvs(size=(N, self.n), rng=rng)

I agree, the single instance is because of the old aversion to OOP.
But loc-scale families and having a pretty strict pattern in distribution also has the advantage that we have a single framework that can implement a lot of features with little effort because distributions don't have to be special cased.
We are getting more proposals for distributions that don't fit well in the current pattern.
I don't see a problem adding new classes outside of the current framework, with maybe reusing parts that are still common.
However, the current pattern works very well for most standard distributions, e.g. almost all my pvalue calculation are just norm.sf(...), t.sf(..), f.sf(..) and some noncentral versions for power.

distcan and similar package before that don't work for implementing distributions in a generic way.
It's built on too many special cases, and those special cases are often not even the same across fields. On Wikipedia several distributions have several "canonical" parameterizations. For other distributions, there are different versions depending on whether they include loc and/or scale, i.e. in the style of 2-parameter pareto vs 3 parameter pareto, and similarly for many distributions.
(some R packages have different distribution names depending on the number of parameters including loc, scale)
statsmodels GLM uses the mean-variance parameterization which is standard in the GLM literature but not "canonical" in the distribution literature. To work around we have functions to convert parameters from GLM to scipy (with occassional problems in figuring out the general parameter transformation. https://stackoverflow.com/questions/60215085/calculating-scale-dispersion-of-gamma-glm-using-statsmodels )
IMO it's better to have a somewhat restrictive framework with 100 distributions and occassional hiccups than to have 15 user friendly distributions with an interface that is "canonical" for users but not maintainers.

@rkern, thanks for the detailed explanation!
As someone coming from Matlab, the intention to avoid OOP sounds strange to me. One of the reasons to switch is that Python is a much more expressive language than Matlab. The old statistics interface in Matlab was indeed a set of functions, but standalone, not bundled in classes or instances. And the modern one in the Stats & ML Toolbox does use classes & objects, unless I'm mistaken in pretty much the way I sketched. Don't get me wrong, I don't think that OOP should be forced upon everything, but I think it is a natural match to modelling distributions.
I don't think that loc and scale should be removed, it just shouldn't be the main way to specify parameters, except for explicit location-scale families. You are right, sometimes applications come up that call for e.g. scaling even though the standard definition does not allow for that. The concern is more that focusing on these parameters may make it harder to create a distribution from "canonical" parameters.
@josef-pkt you are right that there are many cases in which there is not one set of canonical parameters. The normal distribution with standard deviation vs variance is one example, and Wikipedia notes three different parametrizations for gamma. In my ideal world sketched above, there could be several "factory" class methods that transform parameters into the format used by __init__, and maybe get methods that transform internal parameters back.
I don't think that distcan can replace (the interface of) scipy.stats; yes, it is much smaller. But I think more like @rgommers that this is something that could be integrated into scipy.stats, making it more user-friendly (you do want it to be user-friendly, right?) without messing with internals.
But @josef-pkt, I see a bit of a contradiction between criticising distcan for supporting only 15 distributions as opposed to the 100 of scipy.stats, but at the same time defending loc/scale with the argument that the pattern works for "norm.sf(...), t.sf(..), f.sf(..) and some noncentral versions for power". Also, noncentral t is not just a shifted version of t.

The basic structure of the distributions is 10 to 15 years old, AFAIK, and never has fundamentally change. At that time Python was still the underdog, and many developers thought the API has to cater to matlab conventions.
I'm not really criticising distcan or similar. I think they contribute a good user interface and IMO scipy should eventually add more support for less confusing interfaces or distributions that don't fit the standard pattern easily. For example, something like frozen distributions could also transform parameters instead of just storing them. But that needs distribution specific work.
However, scipy needs to implement a large number of distribution, also so that other packages can delegate to it. A new distribution that fits the current pattern can be implemented in 15 lines or so and gains all the general features, extensions and even unit tests.
(The same is true for me in statsmodels. For years I have been searching for generic solutions that makes it possible to easily reuse features for new models or to add features that immediately apply to many existing models. This reduces developer time and makes the code more robust because unit tests evaluate features for many different use cases. That doesn't always create an "obvious" api, but then there can be wrappers outside or inside the package.
In short: I'd rather have users complaining that something is not convenient, than complaining that things are not available in Python at all.)
norm.sf(...), t.sf(..), f.sf(..) were more examples where having a single instance is convenient.
stats.TDist().sf(...)   doesn't look as pretty as stats.t.sf(...)

Alright, I didn't expect that you would overhaul the API of scipy.stats because of my issue or someone else's rant. Just take it as my 2 cents. Thanks for engaging with me on that.
To come back to my original question: I take it there is currently not one guide to defining new distributions that covers everything one needs to know (at least none of those I was pointed to cover everything I asked). The advice is basically to go into the code and see how it is done? So maybe I can make this request: That someone who knows this stuff in and out puts such a complete guide together.
I think that would be useful not just for aspiring contributors, but also for simple users. At least in my work, I frequently feel the need to define a particular distribution that isn't useful for anyone else (or at least not many people). And then it is very useful not to have to define everything explicitly, but to benefit from the scipy.stats' automatic filling in, e.g. getting ppf for the price of cdf.
And can I ask, is my implementaton Mixture above correct for a distribution that is not to be contributed?

So maybe I can make this request...

You might be interested in my email to the scipy-dev mailing list on May 8: https://mail.python.org/pipermail/scipy-dev/2020-May/024157.html

Your Mixture class looks fine to me.
I don't know what the current status is with names and similar. They were some required items like adding name of distribution and number or names of shapes.
Shape parameters and name information will not be relevant if there are no parameters.
Your mixture class doesn't have any free parameters. If you need to change a parameter for the underlying distribution, then you need to create a new instance.
If you have bounded support, then I think you still need to implement the limits .a .b.

@WarrenWeckesser, that looks promising!
@josef-pkt, thanks.

If one's viewpoint is that distributions are really a family of distributions, and the main use is to determine the shape parameters (e.g. via fit()), or to evaluate the distribution's pdf|cdf|sf|... for many shape parameters simultaneously at one x value (or of x broadcasted with the shape parameters) then a single instance may fit reasonably well.
OTOH, if one's viewpoint is that a distribution really is just one member of a family, specified by the shape parameters, then a single instance can be quite kludgy to deal with.
Some distributions can benefit computationally by precomputing some data (e.g. truncnorm which benefits from calculating the probability in the truncated region as few times as possible.)  Placing that precomputed data inside the single instance breaks thread-safety. This can be worked around but takes a little effort, and depends on the assumption that the pdf|cdf|.. are being called with many x values at once, so the overhead is amortized.
The fact that the frozen distributions are just the pair (distribution, shape parameters) without any ability to store precomputed data can be confusing to users.
One big drawback of the single instance approach is the difficulty of dealing with non-numeric shape parameters.  E.g. gh-12000 which attempts to add the Poisson binomial distribution.  The single shape parameter is really an arbitrary length list of probabilities. There is substantial overhead to computing the pmf|cdf.  Broadcasting can get in the way also.
Similarly gh-6800 was about adding mixtures of distributions, and doesn't fit so easily into the current framework

I guess where specifying distribution parameters in each call comes in handy is when one wants to evaluate e.g. the pdf for many parameter values at once, and broadcasting can be used. Creating one instance for each set of parameters would be inefficient in that case.
@pvanmulbregt how does placing precomputed data inside the single instance break thread-safety?

how does placing precomputed data inside the single instance break thread-safety?

Two threads might access and change the one instance at the same time.
When I initially fixed the distribution code (10 to 12 years ago), there were many cases where attributes were changed by one call but not cleaned up and it produced incorrect results on the next call with different arguments.
Stale state spillovers are a lot of fun to debug, especially when they only show up some of the time.

Two threads might access and change the one instance at the same time.

Couldn't that be prevented by setting instance data only in __init__, and not allowing modifications later?

Couldn't that be prevented by setting instance data only in init, and not allowing modifications later?

That works for attributes that don't depend on the arguments/parameters of the distribution.
For example, the support bounds .a, .b in Poisson and similar are fixed. For cases where .a and .b depend on the parameters, it is more difficult because then they are also attributes that are not allowed to spill over  and need to be set in each call.

In particular, the distribution's __init__ is called when stats.pyis loaded, not the first time the distribution is used.

@allefeld does this answer your questions?

@mdhaber, well I certainly got a lot of information. But I asked 8 questions with a hint there might be more to follow, and only some of them have been discussed.
More importantly, I still think one shouldn't have to go through source code or issues in order to find out these details.
There should be a page in the documentation that includes all the necessary information needed for a user to define a new distributions for their own use, so that the respective object can be used in place of a `scipy.stats´ distribution.
And there could also be a second page that explains how to construct it such that it can be contributed to the package itself (developer's guide).

I agree. It looks like @WarrenWeckesser's is starting to work on these things. His first PR towards this end is gh-12069. It may look more developer-oriented than you had in mind, but I agree that it would be a good idea to make it more clear for users. I recently started working with stats, too, and I also found it confusing.
In the meantime, if you do get the answers to your questions and would like to share some of your hard-earned lessons, it would be great if you could draft the document you wish you had when you started! Perhaps the experts could help polish it, but the best perspective for that sort of thing is from someone who recently learned everything the hard way. The wiki might be a good place to start before worrying about rendering with Sphinx.
Thanks for your patience. Almost everything is done on a volunteer basis, so this might take a bit of time.

I was interested in adding a __repr__ and some other minor customizations to scipy.stats.norm, but my first few guesses  were not successful.
Attempt 1: without reading any docs.  I just assumed scipy.stats.norm was a plain-old class and e.g. .pdf was a classmethod with some logic to check whether the RV was frozen or not.
class Gaussian(scipy.stats.norm):
    def __repr__(self):
        return f'N({self.mean()}, {self.var()})'
belief = Gaussian(0, 1)
print(belief)

>>> <scipy.stats._distn_infrastructure.rv_continuous_frozen object at 0x7f13e2af4190>

Attempt 2: after reading the docs on rv_continuous
class Gaussian(scipy.stats.rv_continuous):
    def __repr__(self):
        return f'N({self.mean()}, {self.var()})'

    _pdf = scipy.stats.norm._pdf
belief = Gaussian(0, 1)
print(belief)

>>> N(0.24197072451914342, 0.3420761469262813)


@opentelemetry/host-metrics doesn't work on arm64 machine, working fine on amd

What version of OpenTelemetry are you using?
0.50.0
What version of Node are you using?
14.17.6
What did you do?

added auto-instrumentation-node with http and express enabled
added host-metrics instrumentation as provided in the docs
What did you expect to see?
expected to see the host metrics like system_cpu_utilisation etc. in prometheus
What did you see instead?
can't see any host metrics at all, only available metrics are http ones
Additional context

This is happening on an arm64 machine, on the amd machine its working fine I can see the metrics of that machine in prometheus

Hi @architgarg95
would you mind to share

the instrumentation code
how do you start the SDK (code inlined in the main file, using --require, ...)
if you're using any kind of bundler

Thanks!

Hi @david-luna ,
I have the instrumentation code inlined in the main file, please find below the code:

const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { ExpressLayerType } = require('@opentelemetry/instrumentation-express');
const instrumentations = getNodeAutoInstrumentations({
  '@opentelemetry/instrumentation-fs': {enabled: false},
  '@opentelemetry/instrumentation-http': {
    enabled: true,
    responseHook: (span, info) => {
      span.updateName(`${info.req.method} ${info.req.path || ''}`);
    }
  },
  '@opentelemetry/instrumentation-express': {
    enabled: true,
    ignoreLayersType: [ExpressLayerType.MIDDLEWARE, ExpressLayerType.ROUTER, ExpressLayerType.REQUEST_HANDLER],
    spanNameHook: ({request}) => {
      return `${request.method} ${request.path || ''}`
    }
  },
  '@opentelemetry/instrumentation-aws-sdk': {enabled: true},
  '@opentelemetry/instrumentation-winston': {enabled: true}
});

const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');
const { Resource } = require('@opentelemetry/resources');
const { SEMRESATTRS_SERVICE_NAME, SEMRESATTRS_DEPLOYMENT_ENVIRONMENT } = require('@opentelemetry/semantic-conventions');
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc');
const { RuntimeNodeInstrumentation } = require('@opentelemetry/instrumentation-runtime-node');

const resource = new Resource({
  [SEMRESATTRS_SERVICE_NAME]: {app_name},
  [SEMRESATTRS_DEPLOYMENT_ENVIRONMENT]: process.env.NODE_ENV,
});

const metricProvider = new PeriodicExportingMetricReader({
  exporter: new OTLPMetricExporter({
    url: ""
  })
});

const sdk = new NodeSDK({
  resource: resource,
  traceExporter: new ZipkinExporter({
    url: ""
  }),
  metricReader: metricProvider,
  instrumentations: [instrumentations
    new RuntimeNodeInstrumentation({
      eventLoopUtilizationMeasurementInterval: 5000,
    })
  ]
});

sdk.start();

const { HostMetrics } = require('@opentelemetry/host-metrics');
const hostMetrics = new HostMetrics({ metricProvider, name: 'closet-admin-app' });
hostMetrics.start();

Node 14 doesn't support it, works fine on Node 16 and later versions on arm machines as well

as stated working fine on Node 16 and later versions, closing issue


[c++ interceptors] Authentication interceptors unable to signal other interceptors not to process the request

Is your feature request related to a problem? Please describe.
I am designing a server interceptor to process a settings protobuf passed as metadata by the client. Some of these settings are dangerous to act on, so it should only process authenticated requests.
Because server interceptors cannot Hijack() requests, there is no available way for the authentication interceptor to signal an authentication failure before the other interceptors (... or application code?) act on the request.
Describe the solution you'd like
Server interceptors handling authentication can halt requests in the POST_RECV_INITIAL_METADATA or POST_RECV_MESSAGE phase, return the UNAUTHENTICATED status code, and prevent the application or later interceptors from processing the request.
Describe alternatives you've considered
Current workaround idea is to set a metadata field named cancelled to halt processing on the downstream interceptors.
Additional context
C++ interceptors are marked as experimental, probably due to unsatisfaction with the design. This user story should help make a better design.

Thanks for the suggestion!
One of the reasons why server interceptors do not have Hijack() capability is because we did not have a usecase for it. There were also arguments against it suggesting that giving interceptors the ability to Hijack() is too much power since you could potentially write the entire server in the interceptor with that.
I do feel that there is merit in the Hijack() if it is to be used with an authenticating interceptor, but looks like for authentication we already have a way to do this through ServerCredentials.
What do you think @vjpai ?

I came up with the same problem.
It seems that sever-side interceptors are allowed to hijack requessts in other languages, for example in Go.
So i find it a strange solution to forbid this feature in C++.

@yashykt thank you for the information. I think that there are more positives in enabling Hijack() rather than preventing it based on the argument:

much power since you could potentially write the entire server in the interceptor with that.

Documentation could provide some good practices but from there on the responsibility lies with every developer who decides to go for it. As a developer can opt to write a 3000 line procedure, in the same way a developer can decide to write an entire server in the interceptor. A framework cannot be restricted based on a developer's bad implementation decisions. The interceptor API is quite clean when it comes to mis-usage but that does not mean the implementation is a grpc responsibility.
As @igor-sirotin mentioned this is available in other language implementations which renders this as an inconsistency, which is quite bad for a framework.

@yashykt @vjpai same issue here. How to introduce OAUTH2 token based authentication in a c++ server? You bring this even up in your documentation: https://grpc.io/docs/guides/auth/
Please reconsider allow Hijack() for server side authentication.


Linux build support

Adds a yml workflow to validate Linux build support.
Fixes: #2287

@ChrisDenton @riverar @chyyran this does not imply Linux support 😊 but this does appear to restore the build support that was previously available. Let me know if this looks good to you.

This is working for me, thanks!

This works for me, thank you!


KubernetesContainerFactory: security context for user actions

Drop the NET_RAW and NET_ADMIN capabilities from the containers
created to execute user actions (matches DockerContainerFactory).

Codecov Report

Merging #4675 into master will decrease coverage by 5.85%.
The diff coverage is 0%.

@@            Coverage Diff             @@
##           master    #4675      +/-   ##
==========================================
- Coverage   84.41%   78.55%   -5.86%
==========================================
  Files         193      193
  Lines        8711     8712       +1
  Branches      598      596       -2
==========================================
- Hits         7353     6844     -509
- Misses       1358     1868     +510

Impacted Files
Coverage Δ

...re/containerpool/kubernetes/KubernetesClient.scala
23.91% <0%> (-0.18%)
:arrow_down:

...core/database/cosmosdb/RxObservableImplicits.scala
0% <0%> (-100%)
:arrow_down:

...ore/database/cosmosdb/cache/CacheInvalidator.scala
0% <0%> (-100%)
:arrow_down:

...core/database/cosmosdb/CosmosDBArtifactStore.scala
0% <0%> (-95.79%)
:arrow_down:

...tabase/cosmosdb/cache/CacheInvalidatorConfig.scala
0% <0%> (-94.74%)
:arrow_down:

...sk/core/database/cosmosdb/CosmosDBViewMapper.scala
0% <0%> (-92.6%)
:arrow_down:

...e/database/cosmosdb/cache/ChangeFeedListener.scala
0% <0%> (-86.67%)
:arrow_down:

...e/database/cosmosdb/cache/KafkaEventProducer.scala
0% <0%> (-76.48%)
:arrow_down:

...whisk/core/database/cosmosdb/CosmosDBSupport.scala
0% <0%> (-74.08%)
:arrow_down:

...a/org/apache/openwhisk/common/ExecutorCloser.scala
0% <0%> (-66.67%)
:arrow_down:

... and 11 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 673d5c7...e966a0e. Read the comment docs.


runtime/trace, cmd/trace: include CPU profile samples

The trace viewer UI provides a mechanism for displaying CPU profile stack samples.
Access to that data inline with other execution trace data—seeing what functions are being executed by goroutines that run for a surprisingly long time—would have been very helpful for diagnosing bugs like #14812, #16293, and #16432. Though the time for those specific bugs may have passed, I think that Go and its users will encounter similar bugs in the future (either in the runtime or in user code).

@aclements, this is what confused me!

Yes! There are places to improve (some day), but those can get new issues.


Adding commit message to zipDeploy payload

Resolving https://github.com/Azure/webapps-deploy/issues/118
Not using action.yml for taking the input of commit-message

Please add tests also for this change


Since we speak only about Reader interface, use singular of the word "interface"

Fix small minor typo

@googlebot I signed it!


copy: use SSHArgs if copying to a single remote host.

This lets us use ControlPath with the connection, so that if a small number of copies run in parallel we can reuse the connection, rather than failing when too many connections are in flight.  Note that this only works if there's a single remote host; if the copy involves multiple hosts (limactl copy one:/some/path two:/some/path), the syntax does not allow for separate configuration, so we have to fall back to the old way without a ControlPath.
Having too many copies in parallel will still hit any limits imposed by MaxSessions (default 1), at which point scp falls back to not using the control connection (and may hit MaxStartups instead).

There will be some effect: MaxSessions defaults to 10.  But most of the effect will be from bumping that up too.

There will be some effect: MaxSessions defaults to 10.

Your PR description said:

Having too many copies in parallel will still hit any limits imposed by MaxSessions (default 1),

which made it look like there is no effect (but I think I also remember that 10 is the actual default).

Sorry, that default 1 was a typo; fixed :)


Investigate using hapi-pino vs boom

A suggestion from WHOI which have moved the server error logging from the native hapi "Boom" package to the hapi/pino package.
In looking at the code, hapi-pino is ~50 lines shorter but it's worth investigating what other pros/cons exist.

pino integrated in version 2.2.0


Password entry hover-over displays html tags in the message

Password entry hover-over displays html tags in the message, like .

This is a knockvalidation feature. we recommend that you turn off the insertion of titles <form class="form-horizontal" data-bind="validationOptions: { insertMessages: false, allowHtmlMessages: true, errorsAsTitle: false }"
We will update our documentation as needed. Thank you


Host Questionnaire Page typo fixed

Hi Karthick,
We appreciate your interest in this project! However, we are planning to use these issues as an educational tool for our team members to practice using git and GitHub. For that reason, I will be closing your Pull Requests without merging them.
Thank you!


Form elements

Changes

removed loads of unused icons
tweaked how icons work
added textarea to patterns
improved how form element attributes are mapped

Test

npm run compile
check /pattern-library/styleguide/form-elements looks normal

Needs rebasing

Anyone picking this up to merge?


Build tool should only rebuild files that are expired

Currently the build shell rebuilds all assets when asked.  It would be nice if it only rebuilt the assets that have components newer than the build file.  This would make individual builds faster.  There should probably be a flag like --force to make all the files rebuild.

Issues with multiple timestamps should be resolved as of [e70174722a1adf3df8db7059f11824e0d1639cd8]


[backport] Add test cases for various shapes as function input

Backport of #3744

jenkins, test this please.

LGTM!


Can't get to pn532 to compile with esp32 esp-hal

I'm trying to get this to work with esp32 using esp-hal (the no_std version of esp32 rust framework) and I can't get a simple application to compile.
I noticed that this library is based on embedded_hal 0.2.7 which was released in Feb 9, 2022, so it's pretty old and I'm using current esp-hal that is compatible with embedded_hal 1.0 .
So is this indeed the case and the code can't really work with today's embedded_hal?
Is there a way to get it to work by doing some extra work of implementing some interfaces or something?

Updating to embedded-hal 1.0 has been on my backlog for a while now. Sorry it hasn't happened yet. (I would welcome a PR)

I'm willing to take a shot at this. Do you expect it to be complex?

You should be able to write something like this replacing the generic with the concrete ESP I2C type https://github.com/WMT-GmbH/pn532/blob/master/src%2Fi2c.rs#L18-L67

I just did it, but it seems the Timer also needs to be dealt with. I now receive an error, haven't had a chance to look into it yet, so just sharing:

    |
156 | if let Err(e) = pn532.process(&Request::sam_configuration(SAMMode::Normal, false), 0, 50.ms()){
    |                       ^^^^^^^ method cannot be called due to unsatisfied trait bounds
    |
   ::: /Users/my_user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-hal-0.19.0/src/timer/timg.rs:361:1
    |
361 | pub struct Timer<T, DM>
    | ----------------------- doesn't satisfy `_: CountDown`
    |
    = note: the following trait bounds were not satisfied:
            `esp_hal::timer::timg::Timer<TimerX<TIMG0>, Blocking>: embedded_hal::timer::CountDown`

Ah yeah, eh1 removed the CountDown trait without a replacement.
In your case using a newtype around the timer and implementing the CountDown trait should get you going.
For a general implementation I'm not sure how to proceed. Maybe we should provide our own timeout trait.
I would guess that a PR won't be much more complicated than your own ESP implementation. But it might take some time to get everything (including the doc tests) compiling

I tried compiling with latest eh1, mostly needed to remove lines with trait constraints, etc.
Error seem to also have been changed, I just replaced all references to "Error" (which is now a Trait) with references to "ErrorKind" (which is an Enum) and errors disappeared, I'm not sure that's the right approach.
I'm now left with compilation errors only on Time/timer which were removed from eh1 before release (https://github.com/rust-embedded/embedded-hal/issues/359) .
I'm not sure there's an alternative out there until eh brings it back, so it probably needs to be brought back in this crate and left to be implemented per platform?

I managed to get it to compile with eh1 and now getting it to work on ESP32 (not including tests yet).
Added a timer trait to take care of the Countdown removal from eh1.
Eventually I managed to get it working but facing several issues, not completely sure if these are ESP32 related or PN532 related or this library related or maybe my eh1 changes related.

On write I get from esp32 i2c timeout errors when I don't set timeout, if I set a large timeout it usually work. I assume it is esp_hal related so will ask also there, but in case it isn't then writing it here as well.

There's a wait_ready issue, it's supposed to read 0x01 before fetching the data that comes next, but the data that comes later also comes with the 0x01 again. I tried doing multiple reads of one byte, and they all bring 0x01 and still the larger buffer read reads the 0x01 at the beginning of the buffer. I also added println! in between so it's not a timing issue as described on the related issue mentioned there. So I modified the read function to skip first byte and now it seems to work (at least with my very limited testing, fetching firmware version), but that's probably not the design. Any ideas what this could be related to? Either, that's how it should work, or it's my PN532, or an esp32/esp_hal issue.

Awesome work! Thanks for taking the time.

 The pn532 can be quite slow sometimes.
This is expected behavior. If you check the linked i2c implementation you'll see that we also skip the first byte in the read method

Awesome work! Thanks for taking the time.
1.  The pn532 can be quite slow sometimes.

I've place 1000000 there, but they don't specify in the docs what units it is. Also, I'd assume when I put None (which is an option, even the default option) there won't be a timeout. Sometimes I get a timeout even with that value, if I turn off/on the pn532 then it gets fixed.

2. This is expected behavior. If you check the linked i2c implementation you'll see that we also skip the first byte in the `read` method

Yes, the way it's done in the original code is by passing two read operations, first is supposed to fetch the 0x01 and the following the rest of the data.
What I see  is that the first byte indeed comes as 0x01, but then it arrives again in the following read. And even if I do 5 read operations of a single byte that single byte is always 0x01, and until I don't read a larger buffer the buffer has that 0x01 as first byte.
For example, the ack reads as (from logs) :  [1] then [1, 0, 0, 255, 0, 255]
I don't know whether it is a PN532 I2C issue (is it aware of each read operation and can respond with that first byte over and over again) or an esp32/esp_hal internal buffering bug?
So what I did is to combine the two parts into a single larger read operation and copy the byte starting with the 2nd to the passed buffer. Less elegant since I need to assume a max buffer internally (esp32 max I2C is 32 bytes so I have a limit).

Hm the timeout thing seems strange, but maybe the problems will disappear after we fix the other issues.
For the two reads you'll need to use
https://docs.rs/embedded-hal/latest/embedded_hal/i2c/trait.I2c.html#tymethod.transaction instead of two separate reads.
What kind of tag are you reading? Maybe ntag_read is the wrong request for you.
Anyways you can increase the const generic N of the Pn532 struct to increase the buffer size.

For the two reads you'll need to use https://docs.rs/embedded-hal/latest/embedded_hal/i2c/trait.I2c.html#tymethod.transaction instead of two separate reads.

This is what I referred to when I was referring to 'two reads'. the text you see above ([numbers] then [more numbers]) is from logs of the two buffers of that single call to transaction.

What kind of tag are you reading? Maybe ntag_read is the wrong request for you. Anyways you can increase the const generic N of the Pn532 struct to increase the buffer size.

I'm using ntag-215 that I wrote a single record to using NFC tools from an iPhone.

Hm this might be a bug in the HAL then.
Would you be able to check with a logic analyzer if the following holds:

Data from adjacent operations of the same type are sent after each other without an SP or SR.
The two reads from a single transaction should appear as just one read on the bus

Hm this might be a bug in the HAL then. Would you be able to check with a logic analyzer if the following holds:
That's what I'm thinking as well. I'll ask there.

Would you be able to check with a logic analyzer if the following holds:
I don't have a logic analyzer.

Anyway, I now switched to test SPI and ... can't get it to work.
It is stuck with wait_ready returning Pending. Value received there is 255.
The changes to the spi.rs are really minimal:

Instead of the several trait bounds on SPI, just have SPI: SpiDevice
Instead of transfer, use transfer_in_place
Error changes to embedded_hal spi Error
I guess I can remove the handling of cs since the SpiDevice takes care of that properly, but for now I gave it a pin (either dummy or the real one, both cases didn't work)

Any ideas what to check?

What frequency to set the spi? I used 100kHz so would be low enough to work.
What SPI mode to use (0,1,2,3)? I tried all, but can't test all permutations of everything.
3 I switched esp32 spi to LSB mode as I saw is required (though tried both), also tried with msb_spi feature
4 Should I do any special non trivial wiring on the PN532 module I'm using? (e.g. RSTO can stay disconnected? I'm also not connecting IRQ at thie stage). I connected cs to the pin named ss, is that correct wiring?
I'm using ExclusiveDevice of embedded-hal-bus to create the SpiDevice to pass to the SpiInterface.

You should use Mode 0 and you can set lsb first with https://docs.rs/esp-hal/latest/esp_hal/spi/master/struct.Spi.html#method.with_bit_order but it seems you've done that already.
Frequency shouldn't matter and 100kHz sounds good.
Full duplex and ExclusiveDevice sounds good.
Chip select handling might be the problem.
Some devices rely on cs to determine when a frame starts and ends. I don't remember if the pn532 works like that.
Could you try using a single transaction instead of multiple write and transfer_in_place calls. That way the cs won't toggle during communications.

Some devices rely on cs to determine when a frame starts and ends. I don't remember if the pn532 works like that.
Could you try using a single transaction instead of multiple write and transfer_in_place calls. That way the cs won't toggle during communications.

Ok, I'll try that.
So if this is how the pn532 work, when I connected cs to Gnd it wouldn't recognize data arriving at all?
On another note: This made me decide to get a simple logic analyzer. Do you happen to know to recommend one that isn't expensive yet good for these type of work? I saw there are those cheap ones Salea 8 channel clones, are these recommended? What's the next step up from these?

I use one from Kingst and I'm quite happy with it. Don't know how it compares to others.

I replaced the wait_ready to use transaction, same results.
I keep getting 8 as response.
I tried changing the data I send in the request and it does change the response, which means the device does react in some way even if not as the code expects.
Maybe the 8 has some meaning in PN532? (the ack is supposed to be 1).
I went into the PN532 user manual, and found this diagram:

It shows that after a command the host is supposed to poll until it receives status 0x01.
It doesn't say it should also write anything to get that status response.
And this is indeed how the I2C code looks like. wait_ready only includes read.
In the code what's taking place is that the host repeatedly sends STATREAD request, and then 0x00 after that and then reads data back. This is not what I understand from the diagram.
I tried only reading status and it didn't work either, but I don't see where the sequence the code performs is documented.
Any ideas what to try next?

Yeah I'm also not sure what's going on. I assume you checked the wiring and the dip switch position?
I might have a chance to try your changes on Monday. Could you share what you've got so far?

I submitted a PR #22 .
BTW, regarding I2C on esp-hal they confirmed there's some issue and will solve it, but for now it is still broken.
https://github.com/esp-rs/esp-hal/issues/1998

I added async support for I2C (since SPI doesn't work for me) using embedded-hal-async (left the existing semi-async code in there in case of systems without embedded-hal-async support.
It's using maybe-async so not a lot of code duplications.
Would you like me to submit a PR?

Hey, sorry for the delay...
Work has been really busy recently and it'll take me a week or two to get back to this.
Async support sounds great but maybe we'll finish #22 first 😅

I'm not in a rush, it's working for me, also in async 😀
I think the async is part of the eh1 migration but up to you. Let me know when you can get to it.

Hi @yanshay could you please provide a working example somewhere how to get it working with an esp32 and I2C?
I tried to take parts of the existing library and write the frames with the i2c.write function of esp_hal but I only get AckCheckFailed errors and can not figure out how to fix this.
I would really appreciate a short explanation of how it works with a code example. Maybe until the PR gets approved you could be so kind and make your repo public if that is fine for you.
Thanks a lot!

My fork of pn532 is public - https://github.com/yanshay/pn532 (I don't think you can fork a public repo and make it private). It include two branches prefixed with 'yanshay' which you can use depending on what you need.
As for the AckCheckFailed, I had it as well, eventually what I think solved it was reducing the I2c to 20kHz (which is a huge drop from what I remember was the default speed the module is expected to work). And there are still errors that require retries which don't always work. The Pn532 is not that great to work with, especially not the AliExpress clones from what I've read.
Here (attached zip) is some old messy code I used for many trialslto get it working, I verified it to work (on esp32s3) but by no means see it as a good example, it's just many trials I made. It's also on previous version of esp-hal so I believe things changed so it won't compile as is with later versions. It's also using 100kHz, since then I move to 20kHz in my real program, I think due to reliability issues.
esp32s3-nfc.zip

Hi @yanshay, thanks a lot! That helped me to that point that I can successfully read the firmware version.
Somehow I still can not read tags. From the datasheet I expected that when I send the InListPassiveTarget command and received an ACK frame, I would receive a response with the tag UID when I present the tag to the chip. But somehow I never get a response for that command.
I found a similar open issue at the NPX community forum but there is no solution.
Could you please tell me how you read tags or what my issue is here?
This is my current implementation:
use core::fmt::Debug;
use core::task::Poll;
use esp_hal::{
    delay::Delay, i2c::master::Error as I2cErrorHal, i2c::master::I2c, prelude::*, Blocking,
};
use log::info;
const PN532_I2C_ADDRESS: u8 = 0x24;
pub const PN532_I2C_READY: u8 = 0x01;
const PREAMBLE: [u8; 3] = [0x00, 0x00, 0xFF];
const POSTAMBLE: u8 = 0x00;
const ACK: [u8; 6] = [0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00];
const HOST_TO_PN532: u8 = 0xD4;
const PN532_TO_HOST: u8 = 0xD5;
const COMMAND_SAMCONFIGURATION: [u8; 5] = [0xD4, 0x14, 0x01, 0x00, 0x00]; // SAMConfiguration for Normal mode
const COMMAND_ACTIVATE_RFFIELD: [u8; 6] = [0xD4, 0x32, 0x01, 0x01, 0xF2, 0x00]; // RFCommuncation command to activate RF Field

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(u8)]
pub enum Command {
    GetFirmwareVersion = 0x02,
    InListPassiveTarget = 0x4A,
    InDataExchange = 0x40, // 7.3.8 InDataExchange page 127 datasheet
                           // Add other commands as needed
}

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(u8)]
pub enum NTAGCommand {
    Read = 0x30,
}

#[derive(Debug)]
pub enum I2cError {
    WriteError,
    ReadError,
}

#[derive(Debug)]
pub enum Error {
    BadAck,
    BadResponseFrame,
    CrcError,
    Timeout,
    I2cError(I2cError),
    Pn532Error(ErrorCode),
    I2cErrorHal(I2cErrorHal),
}

impl From<I2cError> for Error {
    fn from(e: I2cError) -> Self {
        Error::I2cError(e)
    }
}

impl From<ErrorCode> for Error {
    fn from(e: ErrorCode) -> Self {
        Error::Pn532Error(e)
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum ErrorCode {
    Timeout = 0x01,
    CrcError = 0x02,
    ParityError = 0x03,
    WrongBitCountDuringAntiCollision = 0x04,
    FramingError = 0x05,
    AbnormalBitCollision = 0x06,
    InsufficientCommunicationBuffer = 0x07,
    RfBufferOverflow = 0x09,
    RfFieldHasNotBeenSwitchedOn = 0x0A,
    RfProtocolError = 0x0B,
    Overheating = 0x0D,
    InternalBufferOverflow = 0x0E,
    InvalidParameter = 0x10,
    CommandNotSupported = 0x12,
    WrongDataFormat = 0x13,
    AuthenticationError = 0x14,
    WrongUidCheckByte = 0x23,
    InvalidDeviceState = 0x25,
    OperationNotAllowed = 0x26,
    CommandNotAcceptable = 0x27,
    TargetHasBeenReleased = 0x29,
    CardHasBeenExchanged = 0x2A,
    CardHasDisappeared = 0x2B,
    NfcId3InitiatorTargetMismatch = 0x2C,
    OverCurrent = 0x2D,
    NadMissing = 0x2E,
}

impl TryFrom<u8> for ErrorCode {
    type Error = ();

    fn try_from(value: u8) -> Result<Self, Self::Error> {
        match value {
            0x01 => Ok(ErrorCode::Timeout),
            0x02 => Ok(ErrorCode::CrcError),
            0x03 => Ok(ErrorCode::ParityError),
            0x04 => Ok(ErrorCode::WrongBitCountDuringAntiCollision),
            0x05 => Ok(ErrorCode::FramingError),
            0x06 => Ok(ErrorCode::AbnormalBitCollision),
            0x07 => Ok(ErrorCode::InsufficientCommunicationBuffer),
            0x09 => Ok(ErrorCode::RfBufferOverflow),
            0x0A => Ok(ErrorCode::RfFieldHasNotBeenSwitchedOn),
            0x0B => Ok(ErrorCode::RfProtocolError),
            0x0D => Ok(ErrorCode::Overheating),
            0x0E => Ok(ErrorCode::InternalBufferOverflow),
            0x10 => Ok(ErrorCode::InvalidParameter),
            0x12 => Ok(ErrorCode::CommandNotSupported),
            0x13 => Ok(ErrorCode::WrongDataFormat),
            0x14 => Ok(ErrorCode::AuthenticationError),
            0x23 => Ok(ErrorCode::WrongUidCheckByte),
            0x25 => Ok(ErrorCode::InvalidDeviceState),
            0x26 => Ok(ErrorCode::OperationNotAllowed),
            0x27 => Ok(ErrorCode::CommandNotAcceptable),
            0x29 => Ok(ErrorCode::TargetHasBeenReleased),
            0x2A => Ok(ErrorCode::CardHasBeenExchanged),
            0x2B => Ok(ErrorCode::CardHasDisappeared),
            0x2C => Ok(ErrorCode::NfcId3InitiatorTargetMismatch),
            0x2D => Ok(ErrorCode::OverCurrent),
            0x2E => Ok(ErrorCode::NadMissing),
            _ => Err(()),
        }
    }
}

/// Card type parameter to be used in [`Command::InListPassiveTarget`]
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(u8)]
pub enum CardType {
    /// 106 kbps type A (ISO/IEC14443 Type A)
    IsoTypeA = 0x00,
    /// 212 kbps (FeliCa polling)
    FeliCa212kbps = 0x01,
    /// 424 kbps (FeliCa polling)
    FeliCa424kbps = 0x02,
    /// 106 kbps type B (ISO/IEC14443-3B)
    IsoTypeB = 0x03,
    /// 106 kbps Innovision Jewel tag
    Jewel = 0x04,
}

pub struct Pn532<'d, T>
where
    T: esp_hal::timer::Timer,
{
    pub i2c: I2c<'d, Blocking>,
    pub timer: T,
    buf: [u8; 32],
}

impl<'d, T> Pn532<'d, T>
where
    T: esp_hal::timer::Timer,
{
    pub fn new(i2c: I2c<'d, Blocking>, timer: T) -> Self {
        Pn532 {
            i2c,
            timer,
            buf: [0; 32],
        }
    }

    pub fn init(&mut self) -> Result<(), Error> {
        let delay = Delay::new();
        delay.delay(14000.millis());

        // Step 1: Send a long preamble (at least 8 bytes of 0x00)
        if self
            .i2c
            .write(PN532_I2C_ADDRESS, &[0x00; 8])
            .inspect_err(|e| {
                info!("Error: {:?}", e);
            })
            .is_err()
        {
            info!("Failed to send preamble");
        }
        delay.delay(2000.millis());
        // Step 3: Send the SAMConfiguration command to transition to normal mode
        if self
            .i2c
            .write(PN532_I2C_ADDRESS, &COMMAND_SAMCONFIGURATION)
            .inspect_err(|e| {
                info!("Error: {:?}", e);
            })
            .is_err()
        {
            info!("Failed to send SAM");
        } else {
            info!("Sent SAM");
        }

        if self
            .i2c
            .write(PN532_I2C_ADDRESS, &COMMAND_ACTIVATE_RFFIELD)
            .inspect_err(|e| {
                info!("Error: {:?}", e);
            })
            .is_err()
        {
            info!("Failed to activate RF field");
        } else {
            info!("Activated RF field");
        }
        Ok(())
    }

    fn wait_ready(&mut self) -> Poll<Result<(), Error>> {
        let mut buf = [0];
        self.i2c.read(PN532_I2C_ADDRESS, &mut buf).ok();
        // It's possible that the PN532 does not ACK the read request when it is not ready.
        // Since we don't know the concrete type of `Self::Error` unfortunately we have to ignore all interface errors here.
        // See https://github.com/WMT-GmbH/pn532/issues/4 for more info

        if buf[0] == PN532_I2C_READY {
            Poll::Ready(Ok(()))
        } else {
            Poll::Pending
        }
    }

    pub fn get_firmware_version(&mut self) -> Result<&[u8], Error> {
        let delay = Delay::new();
        delay.delay(2000.millis());
        self.send_command(Command::GetFirmwareVersion, &[])?;
        self.receive_response(Command::GetFirmwareVersion, 4)
    }

    pub fn read_card(&mut self) -> Result<&[u8], Error> {
        self.send_command(Command::InListPassiveTarget, &[1, CardType::IsoTypeA as u8])
            .ok();
        self.receive_response(Command::InDataExchange, 7)
        //self.send_command(Command::InDataExchange, &[1, NTAGCommand::Read as u8, 1])
        //    .ok();
        //self.receive_response(Command::InDataExchange, 7)
    }

    fn send_command(&mut self, command: Command, data: &[u8]) -> Result<(), Error> {
        let data_len = data.len();
        let frame_len = 2 + data_len as u8;
        let mut data_sum = HOST_TO_PN532.wrapping_add(command as u8);
        for &byte in data {
            data_sum = data_sum.wrapping_add(byte);
        }

        const fn to_checksum(sum: u8) -> u8 {
            (!sum).wrapping_add(1)
        }

        self.buf[0] = PREAMBLE[0];
        self.buf[1] = PREAMBLE[1];
        self.buf[2] = PREAMBLE[2];
        self.buf[3] = frame_len;
        self.buf[4] = to_checksum(frame_len);
        self.buf[5] = HOST_TO_PN532;
        self.buf[6] = command as u8;
        self.buf[7..7 + data_len].copy_from_slice(data);
        self.buf[7 + data_len] = to_checksum(data_sum);
        self.buf[8 + data_len] = POSTAMBLE;

        match self.i2c.write(PN532_I2C_ADDRESS, &self.buf[..9 + data_len]) {
            Ok(_) => {
                info!("SUCCESSSSSSSSS!!!!");
                Ok(())
            } // Command sent successfully
            Err(I2cErrorHal::AckCheckFailed) => {
                info!("AckCheckFailed");
                Ok(())
            } // Ignore AckCheckFailed error
            Err(e) => {
                info!("Some other error: {:?}", e);
                Err(Error::I2cErrorHal(e))
            } // Propagate other errors
        }?;
        info!("Wait for ready...");
        while self.wait_ready()?.is_pending() {}
        info!("Wait for ACK...");
        self.receive_ack().ok();
        info!("Recieved ACK...");
        Ok(())
    }

    fn receive_ack(&mut self) -> Result<(), Error> {
        let mut ack_buf = [0; 6];
        self.i2c
            .read(PN532_I2C_ADDRESS, &mut ack_buf)
            .map_err(|_| Error::I2cError(I2cError::ReadError))?;
        if ack_buf != ACK {
            Err(Error::BadAck)
        } else {
            Ok(())
        }
    }

    fn receive_response(
        &mut self,
        sent_command: Command,
        response_len: usize,
    ) -> Result<&[u8], Error> {
        info!("Wait for ready...");
        // Wait for card detection with a timeout
        self.timer.reset();
        let start_time = self.timer.now();
        self.timer.start();
        while self.wait_ready()?.is_pending() {
            if self.timer.now().checked_duration_since(start_time).unwrap()
                > 100_000u64.millis::<1, 100000>()
            {
                info!(
                    "Timeout after {:?} ms",
                    self.timer.now().checked_duration_since(start_time).unwrap()
                );
                return Err(Error::Timeout);
            }
        }
        info!("Reading response...");
        let mut response_buf = &mut self.buf[..response_len + 10];
        response_buf.fill(0);
        self.i2c
            .read(PN532_I2C_ADDRESS, response_buf)
            .map_err(|_| {
                info!("Response buffer: {:?}", response_buf);
                Error::I2cError(I2cError::ReadError)
            })?;
        // strip first byte of response_buf
        let ready_bit = response_buf[0];
        if ready_bit != PN532_I2C_READY {
            info!("Ready bit: {:?}", ready_bit);
            return Err(Error::BadResponseFrame);
        }
        let response_buf = &response_buf[1..];
        let expected_response_command = sent_command as u8 + 1;
        parse_response(response_buf, expected_response_command)
    }
}

fn parse_response(response_buf: &[u8], expected_response_command: u8) -> Result<&[u8], Error> {
    info!("Response buffer: {:?}", &response_buf);
    if response_buf[0..3] != PREAMBLE {
        info!("Preamble wrong: {:?}", &response_buf[0..3]);
        return Err(Error::BadResponseFrame);
    }
    let frame_len = response_buf[3];
    if (frame_len.wrapping_add(response_buf[4])) != 0 {
        info!("Length checksum error: {:?}", &frame_len);
        return Err(Error::CrcError);
    }
    if frame_len == 0 {
        info!("Frame length 0: {:?}", &frame_len);
        return Err(Error::BadResponseFrame);
    }
    if frame_len == 1 {
        info!("Frame length 1: {:?}", &frame_len);
        return Err(Error::BadResponseFrame);
    }
    match response_buf.get(5 + frame_len as usize + 1) {
        None => {
            info!(
                "No data: {:?}",
                &response_buf.get(5 + frame_len as usize + 1)
            );
            return Err(Error::BadResponseFrame);
        }
        Some(&POSTAMBLE) => {}
        Some(_) => {
            info!(
                "Data error: {:?}",
                &response_buf.get(5 + frame_len as usize + 1)
            );
            return Err(Error::BadResponseFrame);
        }
    }

    if response_buf[5] != PN532_TO_HOST || response_buf[6] != expected_response_command {
        info!("Communication byte 5: {:?}", &response_buf[5]);
        info!("Command byte 6: {:?}", &response_buf[6]);
        return Err(Error::BadResponseFrame);
    }
    let checksum = response_buf[5..5 + frame_len as usize + 1]
        .iter()
        .fold(0u8, |s, &b| s.wrapping_add(b));
    if checksum != 0 {
        return Err(Error::CrcError);
    }

    // Check for PN532 error codes
    if response_buf[7] != 0x00 {
        if let Ok(error_code) = ErrorCode::try_from(response_buf[7]) {
            return Err(Error::Pn532Error(error_code));
        }
    }

    Ok(&response_buf[7..5 + frame_len as usize])
}

This is my main:
#![no_std]
#![no_main]

mod pn532;

use esp_backtrace as _;
use esp_hal::{
    delay::Delay,
    i2c::{
        self,
        master::{Config as I2cConfig, I2c},
    },
    ledc::timer::Timer,
    prelude::*,
    timer::{timg::TimerGroup, OneShotTimer},
    Blocking,
};
use esp_println::logger::init_logger;
use fugit::{HertzU32, RateExtU32};
use log::info;
use pn532::Pn532;

const PN532_I2C_ADDRESS: u8 = 0x48;

const LCD_BACKLIGHT: u8 = 0x08;
const ENABLE: u8 = 0x04;
const RS_DATA: u8 = 0x01;
const RS_COMMAND: u8 = 0x00;

#[entry]
fn main() -> ! {
    init_logger(log::LevelFilter::Debug);
    info!("Initializing");

    let peripherals = esp_hal::init({
        let mut config = esp_hal::Config::default();
        config
    });
    let mut i2c = I2c::new(
        peripherals.I2C0,
        I2cConfig {
            frequency: HertzU32::from(20.kHz()), // Reduced frequency to reduce errors on the PN532
            timeout: Some(30000), // 300ms timeout (pn532 can take up to 200ms + 10us to respond from power down and does clock stretching on start)
        },
    )
    .with_sda(peripherals.GPIO21) // SDA Pin
    .with_scl(peripherals.GPIO22); // SCL Pixn
    let timer_group = TimerGroup::new(peripherals.TIMG0);
    let timer = timer_group.timer0;
    let mut pn532 = Pn532::new(i2c, timer);
    pn532.init().ok();

    for address in 0x03..=0x77 {
        if pn532.i2c.write(address, &[]).is_ok() {
            info!("Found I2C device at address 0x{:02X}", address);
        }
    }

    match pn532.get_firmware_version() {
        Ok(version) => info!("Firmware version: {:?}", version),
        Err(e) => info!("Failed to get firmware version: {:?}", e),
    }

    loop {
        match pn532.read_card() {
            Ok(uid) => info!("Card UID: {:?}", uid),
            Err(e) => info!("Failed to read card: {:?}", e),
        }

        let delay = Delay::new();
        delay.delay(2000.millis());
    }
}

Sorry for the quite messy code and thanks in advance.

Hi everyone,
sorry I haven't been following this for a while.
Thanks @yanshay for providing support.
@PhilippTreupel I didn't look at your code in detail but it seems you're missing the sam_configuration command

@PhilippTreupel  I'm using async now, so here is the code I'm using,  I think sync should be similar.
But I surely don't deal with all the internals if i2c.write/read you seem to be doing in your code above. The library handles all of that.
        let res = pn532
            .process(&pn532::Request::INLIST_ONE_ISO_A_TARGET, 17, request_time)
            .await;

then
pn532.process(
            &pn532::Request::GET_FIRMWARE_VERSION,
            4,
            embassy_time::Duration::from_millis(200),
        )
        .await

then
pn532.process(&pn532::Request::INLIST_ONE_ISO_A_TARGET, 17, request_time)
            .await;

Hi thank you all for the support!
I finally found the issue in this 7 year old stack overflow answer. Apparently in order to get the transmitter working running the RFRegulationTest command once on initialization before running the InListPassiveTarget command helps.
After adding this to my init function it worked right away!
Updated code for the init function:
const COMMAND_RF_REGULATION_TEST: [u8; 3] = [0xD4, 0x58, 0x00];

 pub fn init(&mut self) -> Result<(), Error> {
        let delay = Delay::new();
        delay.delay(14000.millis());

        // Step 1: Send a long preamble (at least 8 bytes of 0x00)
        if self
            .i2c
            .write(PN532_I2C_ADDRESS, &[0x00; 8])
            .inspect_err(|e| {
                info!("Error: {:?}\n", e);
            })
            .is_err()
        {
            info!("Failed to send preamble\n");
        }
        delay.delay(2000.millis());
        // Step 3: Send the SAMConfiguration command to transition to normal mode
        if self
            .i2c
            .write(PN532_I2C_ADDRESS, &COMMAND_SAMCONFIGURATION)
            .inspect_err(|e| {
                info!("Error: {:?}", e);
            })
            .is_err()
        {
            info!("Failed to send SAM\n");
        } else {
            info!("Sent SAM\n");
        }

        if self
            .i2c
            .write(PN532_I2C_ADDRESS, &COMMAND_ACTIVATE_RFFIELD)
            .inspect_err(|e| {
                info!("Error: {:?}", e);
            })
            .is_err()
        {
            info!("Failed to activate RF field");
        } else {
            info!("Activated RF field\n");
        }

        if self
            .i2c
            .write(PN532_I2C_ADDRESS, &COMMAND_ACTIVATE_RFFIELD_RETRIES)
            .inspect_err(|e| {
                info!("Error: {:?}", e);
            })
            .is_err()
        {
            info!("Failed to activate RF field retries");
        } else {
            info!("Activated RF field  retires");
        }

        self.send_command(Command::RFRegulationTest, &[0x00]).ok();
        let delay = Delay::new();
        delay.delay(200.millis());
        Ok(())
    }

Thought I'd share in case anyone else is having problems with it.

I'd like to understand, why are you doing the bytes data writing to i2c when this crate has higher level functions to perform all operations?
Is there benefit to that over the built in functions I use?

I published a new release 🥳
The original issue here should therefore be resolved
@PhilippTreupel if you have troubles getting the new version working please open a new issue and I'll do my best to help :)


[2.4] Button callback doesn't trigger on click

In 2.4.0, the button callback doesn't trigger on mouse click. With phone touch works fine (and the same code works under 2.3). Maybe related to the changes to Input.Mouse?
Code (trivial, but you never knows...):
var aButton = this.add.button(400, 300, 'aButton', function() {
			console.log('aButtonCallback');
                        //do stuffs
		}, this);

Can you test this against 2.4.1 please, as they seem to be working fine for me, but there were definitely issues in some browsers with click events on 2.4.0.

In 2.4.1 aren't working both.
Browser: Firefox 39.0 (64bit, I'm pretty sure);
SO: Linux Mint 17 64bit;

It's not working for me too.
It works on chrome for linux / chrome~firefox for windows.

Must be Linux specific. Works fine in Firefox 38, 39 and 41 on Windows and OS X.
In which case I need you to do this please: edit Pointer.start and at the top log out the event, build it and post the results up here. I don't have Linux running anywhere, but I'm surprised it doesn't include the buttons property. Actually you could probably get it by just logging out game.input.mouse.event after clicking.

mousedown { target: <canvas>, buttons: 1, clientX: 409, clientY: 257, layerX: 409, layerY: 257 }

The event is catch properly. After a bit of debugging seems like the Phaser.Pointer.targetObject is set correctly and the touchedHandler executed. And indeed after the window regain focus the callback is correctly executed. After disabling all breakpoints and try again, the event is logged properly but the callback isn't executed again

Ok so that's weird - it's nothing to do with the mouse event itself then? and I can see you've got a buttons property too - so it much be the touchedHandler check itself that is failing? (even though I've barely touched that for ages)

Ok, I debugged deeply and things became more strange.
First, the _toucherHandler is the same for 2.3 and for 2.4.1. THe only difference is in a test (but it's equivalent semantically) and in the comment.
Exactly in that test
if (!this._pointerData[pointer.id].isDown && this._pointerData[pointer.id].isOver)

The log showed
this._pointerData[pointer.id].isDown = false;
this._pointerData[pointer.id].isOver = true;
for a true test, and the logs in the true branch are showed correctly indeed.
For the following click instead this._pointerData[pointer.id].isDown = true; for a false test, and the logs in the true branch are correctly skipped.
This is because in the _releasedHandler, in the test
if (this._pointerData[pointer.id].isDown && pointer.isUp)

this._pointerData[pointer.id].isDown = true;
pointer.isUp = false;
so the true branch is skipped and the this._pointerData[pointer.id].isDown is never set to false again.
In 2.3 pointer.isUp is correctly set to true instead. I don't know if it's a bug or just a correct effect of the changes in 2.4.0 to the mouse pointer.
Still the first click should work fine, but the callback isn't executed

Update: the code
var btn = this.game.add.sprite (200, 200, 'playButton');
        btn.inputEnabled = true;
        console.log(btn);
        btn.events.onInputDown.add(function() {
            console.log('________________callback executed________________________');
            //doStuffs
        }, this);

works for the first click and skip the following, as espected

Button callbacks are working for me with 2.4.1 on Mac OS X and Chrome, but they do not happen on CocoonJS <IP_ADDRESS>.

Could you all please try the latest build in the dev branch. I've uploaded build files as well for you. But I am pretty sure I've found the cause of it and in my tests in native Cordova apps and on Windows and OSX it's working correctly once again.

v2.4.2 "Altara" - Built: Mon Jul 27 2015 13:35:06
Works for Linux Mint and Chrome. Same problem as before for firefox (39.0, up to date). First click detected but callback not executed, onReleaseHandler doesn't set the pointerData.isDown to false and the following clicks are ignored bu the touchedHandler

Firefox on Linux I assume? because it works fine with FF on Windows and OSX.

Could you please try this for me? In Pointer.updateButtons what does FF log out for event.type and event.buttons ? (for both the click down and the release).

Yes, I've tested only Linux 'cause the problem seems to appear only there. But I can see your point. As soon as I have a Win machine at hand (I hope before this night) I will test my code on it, just to be sure that it's a Phaser problem and not something crappy about my code

Result from a single click, what is print and from who
console.trace():
Phaser.Pointer.prototype.updateButtons()
Phaser.Pointer.prototype.start()
Phaser.Mouse.prototype.onMouseDown()
Phaser.Mouse.prototype.start/this._onMouseDown()
"event.type" "mousedown"
"event.buttons" 1
console.trace():
Phaser.Pointer.prototype.updateButtons()
Phaser.Pointer.prototype.move()
Phaser.Pointer.prototype.start()
Phaser.Mouse.prototype.onMouseDown()
Phaser.Mouse.prototype.start/this._onMouseDown()
"event.type" "mousedown"
"event.buttons" 1
console.trace():
Phaser.Pointer.prototype.updateButtons()
Phaser.Pointer.prototype.stop()
Phaser.Mouse.prototype.onMouseUp()
Phaser.Mouse.prototype.start/this._onMouseUp()
"event.type" "mouseup"
"event.buttons" 1

Interesting - so it does actually have the buttons property, but the value is always 1.

Yep. Instead of an array of buttons, it's set to 1 for the left click, 2 for the right click, etc.

I've been having the same problems.
Browser: Firefox 39.0 (64bit)
OS: Linux Fedora 22 (64bit)
While trying to debug the problem I discovered something that may help narrow down the problem.
In Firefox, I brought up the Developer Debugger, and on the right side under Events checked off mousedown and mouseup. Then, I went to click on a Button object, and when the debugger stops the script I click the button a few times, hold down Ctrl, step over one line of code, and press play.
After that, the callback gets called.

I think the only way to debug this properly is for me to install a VM or similar. Any recommendations on distros?

Ubuntu 14.04 or 15.04, those are the most common

I have Ubuntu 14 running at the moment and can replicate it - the buttons value is populated, but utterly incorrect. Adding in a work-around now.

Ok this should be good now - please try the new dev branch build

Works fine on Firefox 39.0, Linux Mint 17 64bit

Works on Fedora 22 as well :)

Awesome :) Will do some more tests on touch devices, but it's looking good for 2.4.2 this week then.

Touch controls work with v2.4.2-dev on CocoonJS v.<IP_ADDRESS> now! Thanks so much @photonstorm ! I think I'm going to upgrade from 2.2.2`.

Awesome. I'll push out 2.4.2 today then.


Mac mini M1: no cpu temperature, incorrect FAN RPM values

Something is wrong...

Seems to not show any info on MacBook Air M1.

Can Reproduce in my MacBook Air M1 too.

Can Reproduce in my MacBook Air M1 too.

Same with Big Sur

Same with Big Sur

Same here on my M1 MacBook Pro
Is this project even active in development ?

the same on my Macbook Air M1

+1


Staging switch

This is not the most beautiful or full-featured implementation, but I hope it will do for now. The idea is just to provide a quick way for users to access the staging environment to help us test and try out new features.
In a ideal world, I would have implemented this in a way that is a little more robust ...e .g. some better things to do would be:

check to be sure the current url is not the same as the relocate url
allow for an alternate config file specified for the relocate environment
make the relocate directive more self contained and not deployed in the help menu but as a nav bar icon, etc.

But I don't have a lot of time to put into it right now and really need this deployed on Perseids ASAP.
As currently coded, we'll just have to have different versions of the perseids.json conf file in the deployment branch and in the master branch to have different configurations for the relocation handler for each.
@Christof @LFDM if either of you want to give me the nod to go ahead with it as-is over the weekend, I would very much appreciate it. If not, I will do without :) My plan is to merge and deploy on Monday 19 January first in this branch, and then master (deploying master to staging on Perseids)

I think we can go ahead and deploy the changes (although I've not tested the changes, just read the source).
I've added some translations and stumbled on a bug which prevented the translations from being shown. If a translation file contains invalid json, the parser throws an exception and the language doesn't change. I've added the translation files to the list of files validated by jshint.

thanks @Christof !


[Discovery] - How are we going to implement ProgPow in Quais

We either need to dig for a javascript implementation of ProgPow or use wasm to compile go-quai's implementation.

Use go implementation of ComputePowLight


Document JNDI support in WildFly (JMS client)

Part of rabbitmq/rabbitmq-jms-client#21

We can't merge this into live without releasing JMS client 1.7.0 first.

We have an RC out => merging.


Scratchblocks menu on IE

As reported on this forum topic:

Type a line of text (eg. foo) and press enter ⏎.
Insert the when flag clicked block using the scratchblocks menu.

The textarea now contains:
foo

w[scratchblocks]

when green flag clicked
[/scratchblocks]

Confirmed on IE 11.
If you assign me to fix this, I'll get round to it someday...

Additional scratchblocks menu bug: it doesn't have an option for comments


Add support for https:// URLs

New config value 'https', defaults to false
Swaps https:// or http:// depending on the config value

Thanks. Much appreciated!


Change background color of status bar only (to make it match the background of the terminal)

Hi,
I use base16, and would want the statusbar to have same color, or to appear transparent.  Now it has a dark tint to it.  Tried to find anything related in the docs, or issue.  But came up empty.

Using Tmuxline, and managed to remove the background.  And would love to do the same with Vim :-)
Thank you for the plugin though :-)

How about this configuration?
let s:palette = g:lightline#colorscheme#{g:lightline.colorscheme}#palette
let s:palette.normal.middle = [ [ 'NONE', 'NONE', 'NONE', 'NONE' ] ]
let s:palette.inactive.middle = s:palette.normal.middle
let s:palette.tabline.middle = s:palette.normal.middle

You're the boss man! :-D  Much appreciated!

I never though I'd find an answer for this, thanks man.

I'm getting Undefined variable: g:lightline#colorscheme#wombat#palette
has anything changed or am I just missing something?

@jonmackenzie just tried to solve the same issue,
for me the combination of this code, and the one from https://github.com/itchyny/lightline.vim/issues/381#issuecomment-523529581 worked.
autocmd VimEnter * call SetupLightlineColors()
function SetupLightlineColors() abort
  " transparent background in statusbar
  let l:palette = lightline#palette()

  let l:palette.normal.middle = [ [ 'NONE', 'NONE', 'NONE', 'NONE' ] ]
  let l:palette.inactive.middle = l:palette.normal.middle
  let l:palette.tabline.middle = l:palette.normal.middle

  call lightline#colorscheme()
endfunction

even after putting the above block in my .vimrc, parts of the status line remain colored (specifically the grey parts)

Is there any way to make these parts transparent? I tried to set the grey color to same color as my background, but it produces this weird looking light blue instead, I assume it uses 16-colors instead of 256


Info dialog backend service needs a wrapper (as it is very very slow)

Currently the backend service for the info dialog needs to have a wrapper as it makes waaaay to many calls.

I agree that it's currently making too many calls. For reasons relating to #424 we're in between two api's right now. Once we fully migrate do our version 2 api then we'll be consolidating calls. I'm closing this because it's not a client fix directly and is already part of our backend plan.

Where do i report backend issues?
Right now the backend design is killing the client...
Having a wrapper (i.e. provide an API which makes all these APIs into a single call for the client) on the backend can be done with any API so not sure your reasoning is valid, more importantly you can cache that in your API manager which will make it very very fast at is it pure static data...


Development:  Decrease number of users in server tests

Checklist
General

[ ] I tested all changes and their related features with all corresponding user types on a test server.
[ ] This is a small issue that I tested locally and was confirmed by another developer on a test server.
[ ] Language: I followed the guidelines for inclusive, diversity-sensitive, and appreciative language.
[ ] I chose a title conforming to the naming conventions for pull requests.

Server

[ ] Important: I implemented the changes with a very good performance and prevented too many (unnecessary) database calls.
[ ] I followed the coding and design guidelines.
[ ] I added multiple integration tests (Spring) related to the features (with a high test coverage).
[ ] I added pre-authorization annotations according to the guidelines and checked the course groups for all new REST Calls (security).
[ ] I documented the Java code using JavaDoc style.

Client

[ ] Important: I implemented the changes with a very good performance, prevented too many (unnecessary) REST calls and made sure the UI is responsive, even with large data.
[ ] I followed the coding and design guidelines.
[ ] Following the theming guidelines, I specified colors only in the theming variable files and checked that the changes look consistent in both the light and the dark theme.
[ ] I added multiple integration tests (Jest) related to the features (with a high test coverage), while following the test guidelines.
[ ] I added authorities to all new routes and checked the course groups for displaying navigation elements (links, buttons).
[ ] I documented the TypeScript code using JSDoc style.
[ ] I added multiple screenshots/screencasts of my UI changes.
[ ] I translated all newly inserted strings into English and German.

Changes affecting Programming Exercises

[ ] I tested all changes and their related features with all corresponding user types on Test Server 1 (Atlassian Suite).
[ ] I tested all changes and their related features with all corresponding user types on Test Server 2 (Jenkins and Gitlab).

Motivation and Context

Description

Steps for Testing

Prerequisites:

1 Instructor
2 Students
1 Programming Exercise with Complaints enabled

Log in to Artemis
Navigate to Course Administration
...

Exam Mode Testing

Prerequisites:

1 Instructor
2 Students
1 Exam with a Programming Exercise

Log in to Artemis
Participate in the exam as a student
Make sure that the UI of the programming exercise in the exam mode stays unchanged. You can use the exam mode documentation as reference.
...

Review Progress

Performance Review

[ ] I confirm that the client changes (in particular related to REST calls and UI responsiveness) are implemented with a very good performance
[ ] I confirm that the server changes (in particular related to database calls) are implemented with a very good performance

Code Review

[ ] Code Review 1
[ ] Code Review 2

Manual Tests

[ ] Test 1
[ ] Test 2

Exam Mode Test

[ ] Test 1
[ ] Test 2

Test Coverage

Screenshots

Codecov Report

Merging #6530 (ab6fd02) into develop (b014feb) will increase coverage by 3.96%.
The diff coverage is n/a.

:mega: This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more
Additional details and impacted files
@@              Coverage Diff              @@
##             develop    #6530      +/-   ##
=============================================
+ Coverage      76.52%   80.48%   +3.96%
- Complexity         0    13195   +13195
=============================================
  Files           1263     2349    +1086
  Lines          47439    90068   +42629
  Branches        8860    13295    +4435
=============================================
+ Hits           36301    72493   +36192
- Misses          5700     9682    +3982
- Partials        5438     7893    +2455

see 1088 files with indirect coverage changes

Flag
Coverage Δ

client
76.52% <ø> (ø)

server
84.89% <ø> (?)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b014feb...ab6fd02. Read the comment docs.


Piccolo Admin test app

Hi,
I don't know if it matters, but the Piccolo Admin app in test_apps doesn't work as it should because the Piccolo ORM doesn't support automatic database migrations for Sqlite and we have to manually create the tables to fix it. If you think it would be good to fix the Piccolo Admin test app I can make a PR.

@sinisaos hi and sure, why not? If you want to maintain it - that would be nice.

@Goldziher Thanks for quick response. During the day I will do a PR.