glzr-io / zebar

Zebar is a tool for creating customizable and cross-platform taskbars, desktop widgets, and popups.
GNU General Public License v3.0
161 stars 13 forks source link

Question: What am I missing when adding a new provider? #49

Closed CtByte closed 2 months ago

CtByte commented 2 months ago

Hi,

Thank you for this project, it made me start learning Rust.

I am trying to add a new provider but the "createProviderListener" does not seem to return from the /client-api/src/providers/{new}/create-{new}-provider.ts file.

These are the places I changed so far, including steps from the contribution guide and a few others (I included those in the guide):

  1. /client-api/src/user-config/window/providers
  2. /client-api/src/user-config/window/providers/index.ts
  3. /client-api/src/user-config/window/provider-type.model.ts
  4. /client-api/src/user-config/window/provider-config.model.ts
  5. /client-api/src/providers
  6. /client-api/src/providers/create-provider.ts
  7. /client-api/src/providers/index.ts
  8. /desktop/src/providers
  9. /desktop/src/providers/config.rs
  10. /desktop/src/providers/variables.rs
  11. /desktop/src/providers/manager.rs
  12. /desktop/src/providers/mod.rs

Here is my branch of what I have so far.

I managed to run the project in dev mode (pnpm dev) and I tried different things to figure out what I am missing:

Despite all this, I am still missing something, as the dev console never shows my new provider emitted. I have other questions, but I save those for later :)

Thank you for any hints! (God, I hope it's not a typo)

lars-berger commented 2 months ago

@CtByte To get it wired up, change 'networkactivity' -> 'network_activity' in provider-type.model.ts (and then also use network_activity in the config file)

Because of the ProviderConfig struct, it ends up being network_activity

But also, I don't see issues with adding properties for the network activity to the existing network provider - what do you reckon?

CtByte commented 2 months ago

@lars-berger Thank you, I will try that change soon. I will add more on this to the contribute guide as well. Not sure if there is a way right now, but listing all available provider names in the self might be helpful.

My reasoning for not adding properties to the existing network provider was that it seemed like a "heavy" provider already. There is a lot of information collected on interfaces, gateway, etc. I would expect to update up/down numbers every second, so I wanted to make a lightweight provider just for that.

I am testing a local build where I did just that (expanding the network provider) and the bar seemed overwhelmed after some time. The numbers stopped updating. I changed the interval to 2 seconds instead and removed all the properties from the network provider, leaving only my 2 new fields. It seems to be running more stable like that.

I am sure my Rust code can be better, so I am more than happy to change it and go with your suggestion. I can see the logical reason behind just expanding the network provider though.

On an other note, what I am experiencing right now is that when my computer wakes up from sleep, the number counter updates rapidly (up and down speed, so only my new fields), like it has collected all the requests while in sleep and it does a catch up. Could that be helped by filtering out results from promises that are too old (older than the interval set on the provider)?

I hope I make sense :)

lars-berger commented 2 months ago

@CtByte It's possible to scan for what variables the user uses in their template, so down the road, it'd be possible to selectively fetch just the variables that are necessary. So IMO it makes sense to design providers with that in mind, even though it might introduce some extra latency for now especially with super low refresh intervals.

Still, we wouldn't want the bar to freeze up. Do all providers freeze when the interval is at 2s?

And on wake, is it only the network activity variables that update rapidly? My guess is that it's the refresh call here that completely freezes up while the computer is on standby. And since it's synchronous, we can't cancel the network activity from refreshing on the rust side AFAIK. I think you're right about all the promises being stuck in pending while this is happening. It'd be worth adding either a timeout if the same provider makes a fetch while it still has a pending fetch or throw an error on the client-side if it takes too long.

CtByte commented 2 months ago

@lars-berger I completely agree with designing providers logically and indeed, the most elegant solution is to selectively collect data for the client side. I was thinking of adding a new interface for the network provider called "traffic" where I would collect the up/down properties. I would prefer that as well.

After removing all the "unused" properties from the network provider, leaving only the 2 new ones, my bar does not seem to freeze up with the 2-second update. So far, I did not experience that "catch up" behaviour (only when the network provider was collecting everything every second).

The other providers I use (memory, cpu, weather) did not "freak out" so to speak. Only Komorebi that can be stubborn sometimes.

I will look into your suggestions, and extend the network provider instead.

This is a really great project, I've had fun learning Rust so far. I want to add to this so I might bother you with more questions later on.

Thank you for your help!

CtByte commented 2 months ago

@lars-berger I have to take it back. I just woke my laptop (after 2 hours) and all the providers did the catch-up. This time it did not freeze the bar, and once the numbers calmed down, they continued to work fine. I probably just did not notice this before as most of the numbers stayed the same. Now that I see my internet traffic, that changes a lot, it is more obvious.

It looked kinda cool, but I assume it is not intended behaviour :)

CtByte commented 2 months ago

@lars-berger I made the change regarding network_activity and it was working. Thank you.

As we agreed, I will delete this provider and extend the network provider instead.

Since we talked about this here, I do have a few questions.

I would really like to add the "selective collection" for providers (or at least look into it) because it seems to be important for performance. I was thinking of using the templating language to collect those fields into a dictionary<provider name, list of fields> (not sure what that would be in Rust yet, I am a c# dev) when the config file is loaded and send the required fields to the provider like as user_requested_fields or something like that. First of all, is that a good idea and where would you collect the fields? If you could point me to the right direction, I would really appreciate that.

Another thing I want to ask about is formatting bytes from providers (can be used for the network and memory providers). I have 2 rust functions taking bytes and returning pretty text like "12.5 MB" or "100 Mb". I can see that javascript is used to format date, but I was wondering if adding a "provider" (takes in bytes returns pretty text) would be useful, so I don't need to rewrite the rust into javascript. I would like to know your thoughts on that.

Other than that I will create a new issue on the "catch-up behaviour" later and close this issue in a bit.

Thank you for your time!