client_rust icon indicating copy to clipboard operation
client_rust copied to clipboard

Public encoding functions?

Open blckngm opened this issue 1 year ago • 4 comments

Sometimes I have already e.g. nodes: Vec<Node> in the application state where Node is like

struct Node {
   url: String,
   requests: AtomicU64,
}

(When you are already working with a &Node, bumping the requests counter is just an atomic inc. It's much more efficient than get_or_create(...).inc().)

And I'd like to expose the requests counter of all nodes as a metric family. It might be possible with the collector API, but it would still require quite some boxing, cloning and iterator mapping.

Instead I'd like to encode the metrics myself, e.g.:

encode_descriptor(&mut buf, ...);
for n in &ctx.nodes {
    encode_counter_with_labels(&mut buf, [("node", &n.url)], n.requests.load(...));
}
encode_eof(&mut buf);

This will not require any extra allocation or cloning. By fusing the collecting and encoding phase, metrics can be encoded very efficiently.

blckngm avatar Jun 07 '23 05:06 blckngm

I had to do the same, I ended up using Bloc (Already used for other stuff in my app) I created a NavigationBloc, with a ChangeTabEvent, and listening for this event in the HomeTabs Class using BlocListener. Then you can call the same logic you got in your onTap Method

alanlanglois avatar Feb 03 '23 11:02 alanlanglois

@vixez Hi! Did you manage to find the answer?

MadGeorge avatar May 14 '23 19:05 MadGeorge

I had to do the same, I ended up using Bloc (Already used for other stuff in my app) I created a NavigationBloc, with a ChangeTabEvent, and listening for this event in the HomeTabs Class using BlocListener. Then you can call the same logic you got in your onTap Method

Hello @alanlanglois

I'm also using Bloc in my app, but I'm struggling with nested routes and beamer key placement. Could you provide a code example of your implementation?

Retr0sec7 avatar Sep 09 '23 04:09 Retr0sec7

Sure, It's a lot of file, I'll make it short if you have any struggle with my explaination let me know. I have a NavigationBloc (Using Freezed to minimize the boilerplate):

  • a NavigationEvent : const factory NavigationEvent.openSection(SectionName sectionId) = _OpenSectionEvent;
  • a NavigationState : const factory NavigationState.openSection(SectionName sectionId) = _OpenSection;
  • the NavigationBloc itself just pass the event to a state:
on<NavigationEvent>((event, emit) {
     event.when(
       openSection: (sectionId, subSectionId, directSub) {
         emit(const NavigationState.initial());
         emit(NavigationState.openSection(sectionId, subSectionId, directSub));
       }
   });

And then you have your navigation UI component :

Widget build(BuildContext context) {
   ThemeData theme = Theme.of(context);
    return Scaffold(
       // use an IndexedStack to choose which child to show
       body: IndexedStack(
         index: _currentIndex,
         sizing: StackFit.expand,
         children: [
           // use Beamer widgets as children
           Beamer(
             key: _beamerKey0,
             backButtonDispatcher: BeamerBackButtonDispatcher(
                 delegate: _routerDelegates[0]!,
                 routerDelegate: _routerDelegates[0]!,
           ),
           Beamer(
             key: _beamerKey1,
             routerDelegate: _routerDelegates[1]!,
           ),
           Beamer(
               key: _beamerKey2,
               routerDelegate: _routerDelegates[2]!,
           ),
           Beamer(
             key: _beamerKey3,
             routerDelegate: _routerDelegates[3]!,
           ),
         ],
       ),
       bottomNavigationBar: buildBottomNavigationBar(context, theme));
 }
 

 Widget buildBottomNavigationBar(BuildContext context, ThemeData theme) {
  //There you add your bloc listener
   return BlocListener<NavigationBloc, NavigationState>(
           listener: (context, state) {
             state.whenOrNull(
                 openSection: (sectionName,) {
                   int? sectionId = Const.getSectionId(sectionName); //you could also use int I prefer use const :)
                   (sectionId != null)
                       ? _handleOnTabNav(sectionId, subSection: subSection, directSub: directSub)
                       : null;
                 });
           },
         ),
         child: // your navigation bottom bar
    }
    /// And finally the method that change the tab section and the focus on nested nav
    
    _handleOnTabNav(int index) {
       if (_currentIndex != index && index >= 0 && index < _routerDelegates.length) {
        setState(() {
             _prevIndex = _currentIndex; // for back navigation if I remember well
             _currentIndex = index;
           });
  
       _routerDelegates[index]
     }  
   }
         

alanlanglois avatar Sep 09 '23 08:09 alanlanglois