StackStorm should support LDAP roles for RBAC

StackStorm RBAC roles should mirror LDAP roles when using ldap. At least it should be possible to do so with some configuration and mapping.
In general too it would be nice if StackStorm could "slurp" up roles from an external provider for RBAC purposes.

Copying over message from slack since linking to the archive is not always possible -
ckamps [10:18 AM]
@kami: thanks for the follow-ups.  On the lack of automatic LDAP group to role mapping:  This is a pretty key requirement for our enterprise use case given the fact that we have an enterprise access management service that already manages membership of LDAP groups that make up enterprise level role definitions.  Writing, operating and maintaining custom code to synchronize information that is already available via a common interface (LDAP) is not something we're interested in doing.  Enabling LDAP group to role mapping with relatively frequent and automated synchronization is our interest. We don't expect to care about specific users in the configuration of a tool such as StackStorm. It's the roles associated with LDAP groups in which we'd expect to represent user oriented policy.

The way that elasticsearch handles this may be a good reference.
Basically you create a role_mapping.yaml that maps ldap groups to a local group.

@jjm Thanks for the suggestion.
I will look into, it indeed sounds like something similar to what we were thinking about doing :)

It seems like the current LDAP auth/RBAC workflow is something like

having a user login via LDAP (which creates the user in st2)
the user now has an account and permission to do nothing
request that an admin create and sync an assignments file
now the user can refresh/re-login so they have the proper permissions.

Ideally, when a user logs in with LDAP (or other external auth with some concept of groups/roles), they would automatically be assigned to roles based on the groups of which they are a member.
An example from my own Active Directory mapping:
  "memberOf": [
    "CN=Hipchat Users,OU=Hipchat,OU=Groups,DC=domain,DC=com",
    "CN=Systems Support,OU=Shared Services,OU=Distribution Groups,OU=Groups,DC=domain,DC=com",
    "CN=SS - Monitoring Users,OU=User Groups,OU=Groups,DC=domain,DC=com",
    "CN=JIRA - Administrators,OU=JIRA,OU=Groups,DC=domain,DC=com",
    "CN=Confluence - Admins,OU=Confluence,OU=Groups,DC=domain,DC=com",
    "CN=DevOps,OU=Distribution Groups,OU=Groups,DC=domain,DC=com",
    "CN=UNIX-Support,OU=Shared Services,OU=Unix Groups,OU=Groups,DC=domain,DC=com",
    "CN=Unix-Admins,OU=Shared Services,OU=Unix Groups,OU=Groups,DC=domain,DC=com",
    <and many more, 120 groups total>
  ],

So, yeah, we have a lot of groups. I'm sure that some of these groups could map to StackStorm roles.
A few things that become clear after looking at this, the user requirements may be

scope searches to a groups_ou. This would be OU=Groups,DC=domain,DC=com for the above example.
specify a mapping of specific group DNs to StackStorm roles
ignore any external groups that aren't mapped to StackStorm roles
a user's permissions continue to be the union of permissions for all roles (mapped to external groups)
this mapping would be setup by a StackStorm admin in advance

From a usability perspective, the goal here is that a user that's new to StackStorm would be able to login/auth for the first time and immediately be productive with the correct permissions.

@codyaray Thanks for chiming in.
What you wrote is basically what we had in mind after discussing it with some of our existing users and what we plan to implement in the near future :)

The creating an local user in ST2 is not ideal, if we remove an user from AD his account should not need to be cleaned up from another platform.
Really the user should login and get her / his permissions from LDAP and it not create local copies of the accounts.And allow them to start working straight away.

@jjm With LDAP authentication backend you don't need to create any local user in StackStorm (besides system / stanley user that is, but that's not related to auth or RBAC).
Only thing which you need to create / define manually is role definitions and user role assignments. And once this issue is implemented, you will also need to define another file which maps StackStorm roles to AD / LDAP roles.
If you use LDAP backend and you delete user from LDAP, that user also won't have access to StackStorm anymore once the currently active auth token expires. It's true that user role assignment file will be left as it, but that's a feature and can be cleaned / rectified later.

Made any progress on this?

We've been busy with other things so we haven't made any progress on this yet (we also don't have an ETA yet atm).

We're still watching this issue. :)

This is a key requirement for us as well and eagerly waiting for an update on this.  The issue has not been updated in a while and it would be nice if you could chime in whether this is still being considered and if there is real possibility of this being addressed.

Shouldn't title use the term "LDAP groups" vs "LDAP roles" given that groups and not roles are represented via LDAP?
"StackStorm should support LDAP groups for RBAC"

If a community member was interested in driving the implementation, would it be feasible due to what is held back as closed source in support of the overall RBAC capability?

When this feature is implemented, I would like for the current required field group_dns to be eliminated or at least made optional so that all of the authorization rests solely on the use of the LDAP group to role mapping.
If requirement for this setting persists, organizations will continue to have to onboard individual users to some centrally maintained "st2 users" group in addition to role-oriented LDAP groups vs simply deferring to the role-oriented LDAP groups defined elsewhere in the st2 config.
Managing a common "st2 users" LDAP group in addition to the role-oriented LDAP group is unnecessary overhead for an organization to maintain.
https://docs.stackstorm.com/authentication.html#ldap-enterprise-edition

@ckamps Most of the changes for that would actually need to be done in StackStorm core (st2 repo) and not auth backend so in theory it should be possible to do it without having direct access to enterprise bits source code.
As far as group_dns change goes - this would need to be made in the backend. Imo, making it optional is reasonable once we have role sync in StackStorm.

Just a quick update and heads up - I finally started to work on this feature.
When this feature is implemented, operator will be able to write YAML files which contain definition on how to map remote LDAP groups to StackStorm role(s) (those files will most likely live somewhere in /opt/stackstorm/rbac, perhaps /opt/stackstorm/rbac/role_maps or similar).
Here is an example of such definition file - https://gist.github.com/Kami/8f91c75a907f9a7c83048bf3b6bd527d
Keep in mind this is just an example definition proposal - actual terminology, file format and location might / will change (feedback welcome).
As described in the example definition file, those mappings will automatically be synchronized in StackStorm every time user logs-in (authenticates) with StackStorm st2auth API.
If for some reason, admin / operator wants to sync roles earlier or more frequently, we will also provide CLI tool for that (st2-rbac-sync-remote-role-assignments [--user=username] or similar). Keep in mind that this CLI tool will probably be separate from st2-apply-rbac-definitions. Apply definitions tools works locally and is fast and the one for syncing remote group to roles will involve network calls to LDAP server, etc. and be slower and as such, I don't want to conflate those tools together.
If operator wants a more frequent sync, they can also decrease the default value of TTL for the auth token. This means user will need to authenticate more often and as such, roles will be synced more often - that's also really the main purpose behind the auth token (and how most other similar systems are implemented as well) - synchronizing roles on every single API call or similar would simply be too slow and expensive.
The issue name and examples referenced above, etc. mention LDAP, but the whole thing is actually being implemented in a generic fashion by extending functionality provided by auth backends - https://github.com/StackStorm/st2/pull/3280.
This means that the feature won't be tied and coupled to LDAP and users will be able to extend existing auth backends or write new auth backends which allow retrieval of users groups from other places (e.g. from a flat file, from a 3rd party service or product such as various existing user management based HTTP SaaS services,  etc.).
Comments and feedback on terminology, etc. are welcome.
/cc @codyaray @jjm @ckamps @akabraab @lakshmi-kannan @dzimine

Awesome, glad to see it!
On Wed, Mar 8, 2017 at 7:39 AM, Tomaz Muraus<EMAIL_ADDRESS>wrote:

Just a quick update and heads up - I finally started to work on this
feature.
When this feature is implemented, operator will be able to write YAML
files which contain definition on how to map remote LDAP groups to
StackStorm role(s) (those files will most likely live somewhere in
/opt/stackstorm/rbac, perhaps /opt/stackstorm/rbac/role_maps or similar).
Here is an example of such definition file - https://gist.github.com/Kami/
8f91c75a907f9a7c83048bf3b6bd527d
Keep in mind this is just an example definition proposal - actual
terminology, file format and location might / will change (feedback
welcome).
As described in the example definition file, those mappings will
automatically be synchronized in StackStorm every time user logs-in
(authenticates) with StackStorm st2auth API.
If for some reason, admin / operator wants to sync roles earlier or more
frequently, we will also provide CLI tool for that (
st2-rbac-sync-remote-role-assignments [--user=username] or similar). Keep
in mind that this CLI tool will probably be separate from
st2-apply-rbac-definitions. Apply definitions tools works locally and is
fast and the one for syncing remote group to roles will involve network
calls to LDAP server, etc. and be slower and as such, I don't want to
conflate those tools together.
If operator wants a more frequent sync, they can also decrease the default
value of TTL for the auth token. This means user will need to authenticate
more often and as such, roles will be synced more often - that's also
really the main purpose behind the auth token (and how most other similar
systems are implemented as well) - synchronizing roles on every single API
call or similar would simply be too slow and expensive.
The issue name and examples referenced above, etc. mention LDAP, but the
whole thing is actually being implemented in a generic fashion by extending
functionality provided by auth backends - #3280
https://github.com/StackStorm/st2/pull/3280.
This means that the feature won't be tied and coupled to LDAP and users
will be able to extend existing auth backends or write new auth backends
which allow retrieval of users groups from other places (e.g. from a flat
file, from a 3rd party service or product such as various existing user
management based HTTP SaaS services, etc.).
Comments and feedback on terminology, etc. are welcome.
/cc @codyaray https://github.com/codyaray @jjm https://github.com/jjm
@ckamps https://github.com/ckamps @akabraab
https://github.com/akabraab @lakshmi-kannan
https://github.com/lakshmi-kannan @dzimine https://github.com/dzimine
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/StackStorm/st2/issues/2509#issuecomment-285042523,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AACsHoBDwEYQmF0DfLor4HkmftigcNp3ks5rjq-GgaJpZM4HcZI-
.

Just a quick heads up everyone - feature is now (mostly) implemented and working end to end - https://github.com/StackStorm/st2/issues/2509 (docs at https://github.com/StackStorm/st2docs/pull/430).
If you feel a bit adventurous you can check out those changes and test it out.
If you don't want to deal with manually checking out the changes and / or building the packages you can wait a couple of more days for the PR to be reviewed and merged. Once it's merged, new v2.3dev packages will be built and then you can more easily test those (with installer script you just need to use --staging --unstable flag).
Feedback is welcome.
At the very least you can check out the docs and point out if something is not clear or doesn't make sense :)


Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!

Hello, When I run "python3 run.py --env local train --config_path=heal_swin/run_configs/depth_estimation/depth_swin_ train_run_config.py" on a  single 3090 GPU, I met the following errors:
41.3 M    Trainable params
0         Non-trainable params
41.3 M    Total params
165.115   Total estimated model params size (MB)
Validation sanity check:   0%|                                                                                | 0/2 [00:00<?, ?it/s]/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torchvision/transforms/functional.py:1603: UserWarning: The default value of the antialias parameter of all the resizing transforms (Resize(), RandomResizedCrop(), etc.) will change from None to True in v0.17, in order to be consistent across the PIL and Tensor backends. To suppress this warning, directly pass antialias=True (recommended, future default), antialias=None (current default, which means False for Tensors and True for PIL), or antialias=False (only works on Tensors - PIL will still use antialiasing). This also applies if you are using the inference transforms from the models weights: update the call to weights.transforms(antialias=True).
warnings.warn(
/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torchvision/transforms/functional.py:1603: UserWarning: The default value of the antialias parameter of all the resizing transforms (Resize(), RandomResizedCrop(), etc.) will change from None to True in v0.17, in order to be consistent across the PIL and Tensor backends. To suppress this warning, directly pass antialias=True (recommended, future default), antialias=None (current default, which means False for Tensors and True for PIL), or antialias=False (only works on Tensors - PIL will still use antialiasing). This also applies if you are using the inference transforms from the models weights: update the call to weights.transforms(antialias=True).
warnings.warn(
/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torchvision/transforms/functional.py:1603: UserWarning: The default value of the antialias parameter of all the resizing transforms (Resize(), RandomResizedCrop(), etc.) will change from None to True in v0.17, in order to be consistent across the PIL and Tensor backends. To suppress this warning, directly pass antialias=True (recommended, future default), antialias=None (current default, which means False for Tensors and True for PIL), or antialias=False (only works on Tensors - PIL will still use antialiasing). This also applies if you are using the inference transforms from the models weights: update the call to weights.transforms(antialias=True).
warnings.warn(
/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torchvision/transforms/functional.py:1603: UserWarning: The default value of the antialias parameter of all the resizing transforms (Resize(), RandomResizedCrop(), etc.) will change from None to True in v0.17, in order to be consistent across the PIL and Tensor backends. To suppress this warning, directly pass antialias=True (recommended, future default), antialias=None (current default, which means False for Tensors and True for PIL), or antialias=False (only works on Tensors - PIL will still use antialiasing). This also applies if you are using the inference transforms from the models weights: update the call to weights.transforms(antialias=True).
warnings.warn(
/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torchvision/transforms/functional.py:1603: UserWarning: The default value of the antialias parameter of all the resizing transforms (Resize(), RandomResizedCrop(), etc.) will change from None to True in v0.17, in order to be consistent across the PIL and Tensor backends. To suppress this warning, directly pass antialias=True (recommended, future default), antialias=None (current default, which means False for Tensors and True for PIL), or antialias=False (only works on Tensors - PIL will still use antialiasing). This also applies if you are using the inference transforms from the models weights: update the call to weights.transforms(antialias=True).
warnings.warn(
Exception detected, logging run as killed in MLFlow...
Traceback (most recent call last):
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/train.py", line 297, in
main()
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/train.py", line 285, in main
train_model(
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/train.py", line 228, in train_model
trainer.fit(model, dm)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/trainer/trainer.py", line 458, in fit
self._run(model)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/trainer/trainer.py", line 756, in _run
self.dispatch()
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/trainer/trainer.py", line 797, in dispatch
self.accelerator.start_training(self)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/accelerators/accelerator.py", line 96, in start_training
self.training_type_plugin.start_training(trainer)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/plugins/training_type/training_type_plugin.py", line 144, in start_training
self._results = trainer.run_stage()
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/trainer/trainer.py", line 807, in run_stage
return self.run_train()
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/trainer/trainer.py", line 842, in run_train
self.run_sanity_check(self.lightning_module)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/trainer/trainer.py", line 1107, in run_sanity_check
self.run_evaluation()
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/trainer/trainer.py", line 962, in run_evaluation
output = self.evaluation_loop.evaluation_step(batch, batch_idx, dataloader_idx)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/trainer/evaluation_loop.py", line 174, in evaluation_step
output = self.trainer.accelerator.validation_step(args)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/accelerators/accelerator.py", line 226, in validation_step
return self.training_type_plugin.validation_step(*args)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/plugins/training_type/ddp.py", line 322, in validation_step
return self.model(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1518, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1527, in _call_impl
return forward_call(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/parallel/distributed.py", line 1519, in forward
else self._run_ddp_forward(*inputs, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/parallel/distributed.py", line 1355, in _run_ddp_forward
return self.module(*inputs, **kwargs)  # type: ignore[index]
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1518, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1527, in _call_impl
return forward_call(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/pytorch_lightning/overrides/base.py", line 57, in forward
output = self.module.validation_step(*inputs, **kwargs)
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/models_lightning/depth_estimation/model_lightning_depth_swin.py", line 127, in validation_step
loss, preds = self.shared_step(batch, self.val_metrics)
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/models_lightning/depth_estimation/model_lightning_depth_swin.py", line 144, in shared_step
outputs = self(imgs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1518, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1527, in _call_impl
return forward_call(*args, **kwargs)
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/models_lightning/depth_estimation/model_lightning_depth_swin.py", line 91, in forward
outputs = self.model(x.float())
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1518, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1527, in _call_impl
return forward_call(*args, **kwargs)
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/models_torch/swin_transformer.py", line 1126, in forward
x, x_downsample = self.forward_features(x)
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/models_torch/swin_transformer.py", line 1076, in forward_features
x = layer(x)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1518, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1527, in _call_impl
return forward_call(*args, **kwargs)
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/models_torch/swin_transformer.py", line 626, in forward
x = blk(x)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1518, in _wrapped_call_impl
return self._call_impl(args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1527, in _call_impl
return forward_call(args, **kwargs)
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/models_torch/swin_transformer.py", line 381, in forward
attn_windows = self.attn(x_windows, mask=self.attn_mask)  # nWB, window_sizewindow_size, C
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1518, in _wrapped_call_impl
return self._call_impl(*args, **kwargs)
File "/home/liusu/anaconda3/envs/heal_swin/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1527, in _call_impl
return forward_call(*args, **kwargs)
File "/home/liusu/projects/depth_estimation/HEAL-SWIN/heal_swin/models_torch/swin_transformer.py", line 167, in forward
logit_scale = torch.clamp(
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! (when checking argument for argument max in method wrapper_CUDA_clamp_Tensor)
Could you give me some advices?
Thanks a lot!

In the file depth_swin_ train_run_config.py, you may need to modify func get_pl_config to single GPU, here is my version:
def get_pl_config():
from heal_swin.training.train_config import PLConfig
return PLConfig(
    max_epochs=1000,
    gpus=1,
    accelerator="",
    gradient_clip_val=0,
    gradient_clip_algorithm="norm",
)

Hi,
I couldn’t reproduce your error, it works for me... For training on a single GPU, you should set gpus=1 in PLConfig as @ZhuYi2000 wrote. Did that change things? Otherwise, could you check what tensor is on what device?

邮件已经收到！


Why login failed?

Error Information.
error: Failed to login. error:  StatusCodeError: 404 - ""     at new StatusCodeError (/usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/lib/errors.js:32:15)     at /usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/lib/rp.js:70:37     at tryCatcher (/usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/node_modules/bluebird/js/release/util.js:16:23)     at Promise._settlePromiseFromHandler (/usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/node_modules/bluebird/js/release/promise.js:510:31)     at Promise._settlePromise (/usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/node_modules/bluebird/js/release/promise.js:567:18)     at Promise._settlePromiseCtx (/usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/node_modules/bluebird/js/release/promise.js:604:10)     at Async._drainQueue (/usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/node_modules/bluebird/js/release/async.js:143:12)     at Async._drainQueues (/usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/node_modules/bluebird/js/release/async.js:148:10)     at Immediate.Async.drainQueues [as _onImmediate] (/usr/lib/node_modules/node-wechat-terminal/node_modules/request-promise/node_modules/bluebird/js/release/async.js:17:14)     at processImmediate [as _immediateCallback] (timers.js:383:17)

same problem here.

same here

what's the matter? i got same question, then i debugged, when call _webwxnewloginpage function, the request get the 404 error response. But i access the url in my firefox browser, then get in . Maybe some parameters not valid ?  Anyone know ?

It's because there's a 301 redirect. The program did not handle that redirect as good as the browser. This seems to be a underlying library issue.

Request header Host, but  not host

Request header Host, but  not host

Same issue here.

same problem here

I have the same problem. I presume there's no workaround at the moment. Shame, because this package looked good.

It seems this problem continues comes but no solution offered. So I close this issue to be completed. Nearly 6 months passed.


problem in publishing more variables in cloud

Hi, we are trying to publish 7 variables from ESP32 board on ubidots cloud. I changed the pubsubclient.h,  MQTT_MAX_PACKET_SIZE to 1024, but it doesn't seem to work.
The maximum I have been able to publish is 6 variables.
we tested same program with ESP8266 board where we can send more than 10 variables but stuck with ESP32 board.
How we can overcome from this?
Attacging code for your reference.
/****************************************
Include Libraries
/
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>;
/
Define Constants
****************************************/
#define WIFISSID " " // Put your WifiSSID here
#define PASSWORD " " // Put your wifi password here
#define TOKEN " " // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME " " // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string;
//it should be a random and unique ascii string and different from all other devices
#define VARIABLE_LABEL1 "tmp36-1" // Assing the variable label
#define VARIABLE_LABEL2 "tmp36-2"
#define VARIABLE_LABEL3 "tmp36-3"
#define VARIABLE_LABEL4 "tmp36-4"
#define VARIABLE_LABEL5 "obj sensor"
#define VARIABLE_LABEL6 "dht22-temp"
#define VARIABLE_LABEL7 "humidity"
#define DEVICE_LABEL "esp32" // Assig the device label
#define DHTPIN 23
#define DHTTYPE DHT22
//#define SENSOR 12 // Set the GPIO12 as SENSOR
char mqttBroker[] = "things.ubidots.com";
char payload[2000]; //The maximum payload size supported by Ubidots is of 10000 bytes.
char topic[150];
char topic2[150];
char topic3[150];
char topic4[150];
char topic5[150];
char topic6[150];
char topic7[150];
// Space to store values to send
char str_sensor1[60];
char str_sensor2[60];
char str_sensor3[60];
char str_sensor4[60];
char str_sensor5[60];
char str_sensor6[60];
char str_sensor7[60];
//char str_lat[6];
//char str_lng[6];
DHT dht(DHTPIN, DHTTYPE);
/****************************************
Auxiliar Functions
**************************************/
WiFiClient ubidots;
PubSubClient client(ubidots);
void callback(char topic, byte payload, unsigned int length) {
char p[length + 1];
memcpy(p, payload, length);
p[length] = NULL;
String message(p);
Serial.write(payload, length);
Serial.println(topic);
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
// Attemp to connect
if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
Serial.println("Connected");
} else {
Serial.print("Failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 2 seconds");
// Wait 2 seconds before retrying
delay(2000);
}
}
}
/****************************************
Main Functions
****************************************/
void setup() {
Serial.begin(115200);
dht.begin();
WiFi.begin(WIFISSID, PASSWORD);
// Assign the pin as INPUT
//pinMode(SENSOR, INPUT);
Serial.println();
Serial.print("Wait for WiFi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi Connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
client.setServer(mqttBroker, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
int sensor1 = analogRead(36);
int sensor2 = analogRead(39); //temp 2
int sensor3 = analogRead(34); //temp 3
int sensor4 = analogRead(35); //temp 4
int sensor5 = analogRead(32); //IR Object sensor
float voltage1 = sensor1 / 1023.0;
float voltage2 = sensor2 / 1023.0;
float voltage3 = sensor3 / 1023.0;
float voltage4 = sensor4 / 1023.0;
float voltage5 = sensor5 * (3.3 / 4095.0);
float temp1 = (voltage1 - 0.5) * 100.0;
float temp2 = (voltage2 - 0.5) * 100.0;
float temp3 = (voltage3 - 0.5) * 100.0;
float temp4 = (voltage4 - 0.5) * 100.0;
float hum = dht.readHumidity();
float temp = dht.readTemperature();
/* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
dtostrf(temp1, 4, 2, str_sensor1);
dtostrf(temp2, 4, 2, str_sensor2);
dtostrf(temp3, 4, 2, str_sensor3);
dtostrf(temp4, 4, 2, str_sensor4);
dtostrf(voltage5, 4, 2, str_sensor5);
dtostrf(temp, 4, 2, str_sensor6);
dtostrf(hum, 4, 2, str_sensor7);
sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
sprintf(payload, "%s", ""); // Cleans the payload
sprintf(payload, "{"%s":", VARIABLE_LABEL1); // Adds the variable label
sprintf(payload, "%s {"value": %s", payload, str_sensor1); // Adds the value
sprintf(payload, "%s } }", payload); // Closes the dictionary brackets
Serial.println("Publishing data to Ubidots Cloud");
Serial.println(payload);
client.publish(topic, payload);
sprintf(topic2, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
sprintf(payload, "%s", ""); // Cleans the payload
sprintf(payload, "{"%s":", VARIABLE_LABEL2); // Adds the variable label
sprintf(payload, "%s {"value": %s", payload, str_sensor2); // Adds the value
sprintf(payload, "%s } }", payload); // Closes the dictionary bracket
Serial.println("Publishing data to Ubidots Cloud");
Serial.println(payload);
client.publish(topic2, payload);
sprintf(topic3, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
sprintf(payload, "%s", ""); // Cleans the payload
sprintf(payload, "{"%s":", VARIABLE_LABEL3); // Adds the variable label
sprintf(payload, "%s {"value": %s", payload, str_sensor3); // Adds the value
sprintf(payload, "%s } }", payload); // Closes the dictionary bracket
Serial.println("Publishing data to Ubidots Cloud");
Serial.println(payload);
client.publish(topic3, payload);
sprintf(topic4, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
sprintf(payload, "%s", ""); // Cleans the payload
sprintf(payload, "{"%s":", VARIABLE_LABEL4); // Adds the variable label
sprintf(payload, "%s {"value": %s", payload, str_sensor4); // Adds the value
sprintf(payload, "%s } }", payload); // Closes the dictionary bracket
Serial.println("Publishing data to Ubidots Cloud");
Serial.println(payload);
client.publish(topic4, payload);
sprintf(topic5, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
sprintf(payload, "%s", ""); // Cleans the payload
sprintf(payload, "{"%s":", VARIABLE_LABEL5); // Adds the variable label
sprintf(payload, "%s {"value": %s", payload, str_sensor5); // Adds the value
sprintf(payload, "%s } }", payload); // Closes the dictionary bracket
Serial.println("Publishing data to Ubidots Cloud");
Serial.println(payload);
client.publish(topic5, payload);
sprintf(topic6, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
sprintf(payload, "%s", ""); // Cleans the payload
sprintf(payload, "{"%s":", VARIABLE_LABEL6); // Adds the variable label
sprintf(payload, "%s {"value": %s", payload, str_sensor6); // Adds the value
sprintf(payload, "%s } }", payload); // Closes the dictionary bracket
Serial.println("Publishing data to Ubidots Cloud");
Serial.println(payload);
client.publish(topic6, payload);
sprintf(topic7, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
sprintf(payload, "%s", ""); // Cleans the payload
sprintf(payload, "{"%s":", VARIABLE_LABEL7); // Adds the variable label
sprintf(payload, "%s {"value": %s", payload, str_sensor7); // Adds the value
sprintf(payload, "%s } }", payload); // Closes the dictionary bracket
Serial.println("Publishing data to Ubidots Cloud");
Serial.println(payload);
client.publish(topic7, payload);
client.loop();
}

I don't have an ESP32 so I cannot give you any definitive solution here. You don't actually say what doesn't work. If you try sending those packets does the device disconnect? Or do they just silently fail to send?
One theory would be you are overloading something by throwing these publishes at it without giving it a chance to flush anything. You could try adding a yield() call after each publish. You could also, (to help debug, rather than as a solution) see if adding a small delay between each publish helps.

I don't have an ESP32 so I cannot give you any definitive solution here. You don't actually say what doesn't work. If you try sending those packets does the device disconnect? Or do they just silently fail to send?
the device does not disconnect, it seems like it fails to send..
One theory would be you are overloading something by throwing these publishes at it without giving it a chance to flush anything. You could try adding a yield() call after each publish. You could also, (to help debug, rather than as a solution) see if adding a small delay between each publish helps.
I have also added a delay of 500ms between each publish but still only 6 variables are published.


[BUG] RtcEngine.StartRecording(문자열 경로, AUDIO_RECORDING_QUALITY_TYPE 유형) 및 RtcEngine.StopRecording()

Describe the bug
RtcEngine.StartAudioRecording(string path, AUDIO_RECORDING_QUALITY_TYPE type) and RtcEngine.StopAudioRecording()
Using "RtcEngine.StartAudioRecording(string path, AUDIO_RECORDING_QUALITY_TYPE type)" in a WebGL environment obtains AudioFile,
This audio file only has my voice and no one else's voice.
but Windows, Mac, LInux environment, every audience's sound is in the audio file.
To Reproduce
Steps to reproduce the behavior:

Go to 'File' -> 'BuildSetting' -> 'Scenes In Build' and setting Scens index like this : index 0 : API-Example/HomeMenu, Index 1 : API-Example/device-manager/DeviceManager'
Add the global variable within AgoraDeviceManager Class, which bool IsRecording = false;
Add public button (name is  "recordingButton") within AgoraDeviceManager Class
Add Method within AgoraDeviceManager Class, RecordingAction like this :
void RecordingAction()
{
if (IsRecording)
{
IsRecording = false;
_rtcEngine.StopAudioRecording();
}
else
{
IsRecording = true;
string fileName = "SampleAudioRecordFile.wav";
_rtcEngine.StartAudioRecording(fileName, AUDIO_RECORDING_QUALITY_TYPE.AUDIO_RECORDING_QUALITY_MEDIUM);
}
}
In the Awake Method Add this Line. "recordingButton.onClick.AddListener(RecordingAction);"
In the UnityProject Add a new button under the canvas of the DeviceManager Scene
Find the Agora Device Manager class within the Device Manager Scene's Hierarchy and insert the newly added button into the "RecordingButton" of the Agora Device Manager.
Build WebGL And Play Index.html
go to DeviceManager
click to 'JoinChannel'
Click to 'button' and talk to others!
click to 'button'
Then you can get an audio file that is speaking alone in the void.
Copy This Unity Project
Switch platform to Windows, Mac, Linux
Build Project.
Play exe File
Try 9-12 again
you get All Audience voice File

Expected behavior
Like Windows, Mac, and Linux environments, WebGL environments should also be able to obtain audio files that contain the sounds of all audiences.
Desktop (please complete the following information):

OS: Window 10
Browser : 121.0.6167.185 version Chrome
Version : Unity Editor Version 2022.3.15f1 and Agora demo Version Refactor 10 Release

Thanks for providing the steps to reproduce the issue.  Unfortunately, due to the nature of the difference in the platforms, the WebGL SDK does not support recording all users.  If you seek to record only a particular user track, you can try to create new code like the current function startAudioRecording_WGL in  Assets/WebGLTemplates/AgoraTemplate/AgoraWebSDK/libs/audiosystem.js.   However,  there isn't a good solution to record composite users on web using the SDK methods.  To properly get a recording, we recommend using the Cloud Recording service.


[SchemaRegistry] update samples to use asyncio.run

Description
As https://github.com/Azure/azure-sdk-for-python/issues/21207 mentions, some samples are using a loop variable for simple callbacks when this can be done by using the new run method of asyncio. This PR remedies the issue for the schemaregistry library.
All SDK Contribution checklist:

[x] The pull request does not introduce [breaking changes]
[x] CHANGELOG is updated for new features, bug fixes or other significant changes.
[x] I have read the contribution guidelines.

General Guidelines and Best Practices

[x] Title of the pull request is clear and informative.
[x] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

[x] Pull request includes test coverage for the included changes.

/azp run python - schemaregistry - ci


Updating readme to include Pandoc software

git fetch origin
git checkout 106-updating-readme-to-include-pandoc-software


Lighter tick marks

The color is the same as the one of the rendered markdown and button captions.

Im good to merge but Ill have to test for the grid lines


Implement availability operations

These functions still need to be implemented:
https://msdn.microsoft.com/en-us/library/office/bb409286(v=exchg.150).aspx#Anchor_2

<GetRooms> was implemented by @SebastianBecker2 in 87ebf9a. The rest can be added later if needed.


feat(SlashCommandBuilder): add autocomplete

Please describe the changes this PR makes and why it should be merged:
Adds support for autocompletion. This is a draft because I can't figure out the types to make choices and autocomplete exclusive, so any help on this front would be appreciated. I will add tests once the types are figured out.
Relevant links:

Announcement
https://github.com/discord/discord-api-docs/pull/3849
https://github.com/discordjs/discord-api-types/pull/205
https://github.com/discordjs/discord.js/pull/6672

Status and versioning classification:

Code changes have been tested against the Discord API, or there are no code changes
This PR changes the library's interface (methods or parameters added)

Codecov Report

Merging #42 (ea5daeb) into main (c0f7993) will decrease coverage by 1.27%.
The diff coverage is 0.00%.

@@             Coverage Diff             @@
##              main      #42      +/-   ##
===========================================
- Coverage   100.00%   98.72%   -1.28%
===========================================
  Files           18       18
  Lines          233      236       +3
  Branches        33       33
===========================================
  Hits           233      233
- Misses           0        3       +3

Impacted Files
Coverage Δ

...s/slashCommands/mixins/CommandOptionWithChoices.ts
83.33% <0.00%> (-16.67%)
:arrow_down:

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 c0f7993...ea5daeb. Read the comment docs.

This should also include some form of validation in toJSON that checks that if autocomplete is set to true, choices are not present, and if it's set to false or undefined, then it allows choices.

I don't think this is needed because having proper return types that exclude the non-allowed methods is the most that has been done in the rest of the package. However, as I said in the PR description, I can't figure out how to make the types work.

:< no autocomplete


Goodnight Moon

Swap out the moon emoji used for progress spinner for a single-cell character.
The moon emoji looked cool, but couldn't be used because of bugs in xterm.js, used for VSCode's terminal, among others.  The moon emoji is two character cells wide, but xterm.js doesn't advance by two cells when it adds the emoji, but does go back by two when it backspaces.
This changes us to a different character animation (dots) that is only one cell wide, and so doesn't have this problem.

LGTM

It was nice knowing you moon:

Note that my related issue #22303 was asking to not use emoji's at all, also not single-cell ones, as it completely messes up all non-emoji-capable terminal emulators. I see on some terminals just squares with hex code messing up the output.

It's no longer using an emoji, just a regular Unicode character.


Access denied to Ghost 1.6.2

FILL THESE DETAILS FIRST:

Ghost version: 1.6.2
App version: 1.5.6

I tried logging in to a newly installed Docker image of ghost. The image is hosted on a vps without a name. I access the ghost image from a browser using "http://<IP_ADDRESS>:4040"
I created a user and used the credentials but access was always denied. If I enter credentials with an error the application hanged.

Hi @pbout 👋
The Ghost 1.x support in Quill is in beta. You can opt-in to the beta program here: https://play.google.com/apps/testing/me.vickychijwani.spectre
What you downloaded from the Play Store is the stable version of the app (v1.5.6), that currently works only with Ghost 0.11 or older. I'm in the process of rolling out the beta version for everyone over the next few days, or you can start using it now from the link above.
Let me know if you face any issues or need further help!


Feat/master pytest yml instructions

Refer to demo README.md in CONTRIBUTING.md in integration testing instructions
Remove SEARCH OPTIMIZATION references to avoid requiring an enterprise account to test schemachange

Addresses https://github.com/Snowflake-Labs/schemachange/pull/296

@sfc-gh-tmathew and @sfc-gh-jhansen, flagging a few 4.0.0 candidates.

@sfc-gh-tmathew , I see you're firming up the contribution documentation. I've merged master into this branch. I think it adds clarity to the integration test setup steps.

Closing in favor of #298


Enquiry about the received message from the GPS device

I want to Inquire if the received message from the device contain the address by default  of its location or how you get the address that return and saved in the database.
note : I'm using teletonika fm5300

Messages from device don't include address. To retrieve address Traccar uses third party reverse geocoding services:
https://www.traccar.org/reverse-geocoding/

Can I disable this feature , I don't want to retrieve the address using geocoding service , So is there are flag or some thing like that to disable retrieving the address ?

Yes, you can. You need to set geocoder.enable to false:
https://www.traccar.org/configuration-file/


Mark .ember-cli as jsonc instead of json

The .ember-cli file generated by Ember is JSON with Comments (jsonc): https://github.com/ember-cli/ember-cli/blob/master/blueprints/app/files/.ember-cli
I've changed its associated language accordingly because it being the JSON type by default causes red underlines in the generated file.

This PR fixes #110540

Thanks @loganrosen !


Add a way to disable image downloading?

Maybe a feature to disable image downloading and image-link-modification could come in handy. I'll add this feature to the function, but not add a command for it to not feature-spam the CMD interface too much, especially since I can't care for the stability of yet another feature.

I added an extra argument enable_image_downloading (defaults to true) to the Python arguments that does exactly this. I will mark this issue as fixed  and close it now.


dp.change event not fired when the input value is empty

The dp.change event is not fired when the input is empty.
This is because line 828 to 839:
if (newDate.isValid() && !isInDisableDates(newDate) && isInEnableDates(newDate)) { // returns false if `input.val() ==''`
  update();
  picker.setValue(newDate);
  notifyChange(oldDate, e.type);
  set();
}
else {
  picker.viewDate = oldDate;
  picker.unset = true;
  notifyChange(oldDate, e.type);
  notifyError(newDate);
}

If the input value is empty then the moment object returns false when asked if valid so the picker viewDate remains the same. This causes the notifyChange to be called but it returns in line 361:
if (moment(picker.date).isSame(moment(oldDate)) && !errored) {
  return;
}

It returns because the value is never updated.
I understand this logic is fine when the user enters invalid dates, but an empty string should not be consider neither a valid or invalid date.
I need the value to be updated because I am writing an AngularJS directive and the model is not being updated when I clear the input's value:
return function (scope, element, attrs, controller) {
          element.datetimepicker({
            pickTime: attrs.pickTime == 'true',
            format: attrs.format,
            useCurrent: false
          });

          element.on('dp.change',function (e) { // not called when the user clears the input as the value is not updated.
            scope.$apply(function (scope) {
              modelAccessor.assign(scope, e.date);
            });
          });

          scope.$watch(modelAccessor, function (val) {
            var newDate = moment(val);
            element.data('DateTimePicker').setValue(newDate);
          });
        };

Any workaround?
Thanks in advanced.

Sorry I forgot to test it, will do it this week.
On Dec 2, 2014 6:04 PM, "Eonasdan"<EMAIL_ADDRESS>wrote:

@nicolasgarnil https://github.com/nicolasgarnil do you still have this
issue with v4? There was a recent PR that might have fixed this
—
Reply to this email directly or view it on GitHub
https://github.com/Eonasdan/bootstrap-datetimepicker/issues/587#issuecomment-65304144
.

Try v4. Event 'dp.change' doesn't fire on empty value.

I think this still happens on version : 4.7.14


[QUESTION] Default constructor with record classes

With .NET 6's record class, is there any way to specify the constructor?

I've run into the same problem,
a record defined like this  (even all properties are optional) ,cannot be used with LiteDB 5.0.11
    public record class User(
                    int PersonalNumber = 0,
                    string Login = null,
                    string Firstname = null,
                    string Lastname = null,
                    string Location = null,
                    string PhoneInternal = null,
                    string PhoneMobile = null,
                    string ShortCode = null,
                    int? CostCenter = null,
                    string FunctionShort = null,
                    string FunctionLong = null,
                    string GID = null,
                    string Organisation = null,
                    string Email = null,
                    string StockNumber = null,
                    bool InNightDelivery = false);

@seikosantana @farangkao Try using the more Verbose syntax:
public record class User()
{
    public int PersonalNumber { get; init; }
    public string Login { get; init; }
    public string Firstname { get; init; }
    public string Lastname { get; init; }
    public string Location { get; init; }
    public string PhoneInternal { get; init; }
    public string PhoneMobile { get; init; }
    public string ShortCode { get; init; }
    public int? CostCenter { get; init; }
    public string FunctionShort { get; init; }
    public string FunctionLong { get; init; }
    public string GID { get; init; }
    public string Organisation { get; init; }
    public string Email { get; init; }
    public string StockNumber { get; init; }
    public bool InNightDelivery { get; init; }
}

That creates a Parameterless constructor that seems to work in my tests with the object mapper.

public record class User(
                    int PersonalNumber = 0,
                    string Login = null,
                    string Firstname = null,
                    string Lastname = null,
                    string Location = null,
                    string PhoneInternal = null,
                    string PhoneMobile = null,
                    string ShortCode = null,
                    int? CostCenter = null,
                    string FunctionShort = null,
                    string FunctionLong = null,
                    string GID = null,
                    string Organisation = null,
                    string Email = null,
                    string StockNumber = null,
                    bool InNightDelivery = false);

I was running into this issue aswell and noticed that sometimes it does work. With your example it seems that it does not work when using a nullable int.
I am currently looking for a solution within my own application, will share if I find something useful.

So I have a start of a working situation with constructors with parameters.
I have accomplished this using the Activator class after resolving the arguments.
Using the activator class seems to way to go since using BenchmarkDotnet shows that to be a lot faster than using Expressions for this. But I might be overlooking why an other option would be prefered.
Problem now would be dealing with multiple constructors and which to select.
My guess is that you would like to always try to take the parameterless constructor. This will work for records with init only properties as well since you can use PropertyInfo.SetValue(); to set the properties even when they aren't writable.
Maybe just find closest available constructor, most matching parameters. And set the rest afterwards.
Fork that I am working on


Add files via upload

In order to streamline the review of the contribution we ask you
to ensure the following steps have been taken:

[ ] Filename in the lowercase format
[ ] Image format: png
[ ] Image size: 256 by 256 px

@Adam-UNV can you lowercase filename, please?

@Adam-UNV Are you sure it valid contract address ?.

Hi there,
The contract address I submitted in the file name was an ethereum classic
address, as I deployed the token on ETC as a test. Is that supported?
Warm regards,
Adam
On Fri, Jun 22, 2018, 6:11 AM Mykola<EMAIL_ADDRESS>wrote:

@Adam-UNV https://github.com/Adam-UNV Are you sure it valid contract
address ?.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/TrustWallet/tokens/pull/219#issuecomment-399227481,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AlKNsrdtlbHQVWyA20ebkLuGwZm1nzVDks5t-_3TgaJpZM4Ux5ip
.

@Adam-UNV Oh, sorry i did not check ETC. Yes it supported, but please lowercase address.

Added here https://github.com/TrustWallet/tokens/commit/5d92d8c415adc73007aae63e474c969cd2c13304
@Adam-UNV
Also, you can use these graphics to say that your ERC20 token fully compatible with Trust Wallet (https://trustwalletapp.com/logo-assets). Tokens will show up automatically once the user receives them.
Feel free to share this on social media and tag Trust Wallet:

Twitter: @trustwalletapp

Facebook: @trustwalletapp

Great, thanks for that. I'm also having another issue with display of decimals with the ETC token. Can you let me know an email address to send some details?

@Adam-UNV you can always contact via<EMAIL_ADDRESS>


Fix flaky pubsublite test

Fixes https://github.com/elastic/apm-queue/issues/562
This is not a proper fix, but I think it's a hacky improvement.
The problem with the hack in the unit test in https://github.com/elastic/apm-queue/blob/6675642e184c322eadac10a3c6155ed267fc8bdb/pubsublite/internal/telemetry/publisher_test.go#L242 is that the "logic" is tied to the unit test, not in the actual implementation.
Though, this PR does not fully fix the issue, I believe that this PR is a more idiomatic implementation, until we can find a proper solution.
At the core the issue with the goroutine in https://github.com/elastic/apm-queue/blob/6675642e184c322eadac10a3c6155ed267fc8bdb/pubsublite/internal/telemetry/publisher.go#L114 is that we fire-and-forget about it.
The proper solution is to either:

Use wait-group, which to my understanding defeats the purpose of a fire-and-forget strategy
Orchestrate communication between the child and parent, which means we have to update the function interface, by either passing or returning a channel.

I think we could probably consider deleting the pubsublite implementation, since Pub/Sub Lite has been deprecated (see https://cloud.google.com/pubsub/docs/choosing-pubsub-or-lite) and Apache Kafka for BigQuery has been announced. WDYT @marclop?

I'll open a PR to remove pubsublite

@rubvs I think we can close this one. GCP PubSub Lite is no more 🙂


Improve changelog: highlight important changes

It would be nice to highlight important changes in the change log.
E.g. styled-components bumped a major version recently, however, it is unclear what are the breaking changes that required that. As result, it is difficult to foresee the impact of a potential upgrade to that version or what are the things to pay attention to.

I think it's a good proposal, but it could slow us down when merging proposed PRs. Instead we should probably just focus on writing good and readable github release notes. I've just added some for v2.0.0

Completely agree, came here to check the change log file, but couldn't see at a glance if upgrading had any obvious breaking changes.

Ok, I'm going to close this as after further consideration, release notes on github should be a sufficient improvement over the changelog


Stop running use_legacy_dataset=true for wide-benchmark

See https://github.com/apache/arrow/pull/39112

Pull Request Test Coverage Report for Build<PHONE_NUMBER>

0 of 0   changed or added relevant lines in 0 files are covered.
No unchanged relevant lines lost coverage.
Overall coverage decreased (-0.01%) to 87.177%

Totals

Change from base Build<PHONE_NUMBER>:
-0.01%

Covered Lines:
1550

Relevant Lines:
1778

💛  - Coveralls


API docs should be available outside of DTR

File: apidocs/overview.md

@kavikat This is part of my planned work in the near future. The current DTR (and other API pages) can actually be accessed from here: https://docs.docker.com/reference/ with the DTR API specifically linking to https://docs.docker.com/reference/dtr/2.6/api/.


Include additional information in TextDiagramInfoArgs

Whether or not the diagram is transposed.
The relative positioning of the qubits (e.g. so you can determine if they are adjacent and/or in order).

The second of these has been addressed.


[WIP] Vetting locations

116602125

@rjkip, could you take a peek?

So the goal of this PR is to be able send e-mails with one of the two types of vetting locations? If that's the case, :+1:.

Yes, the intent here is to show either RA locations or personal RA details.