 So, so mark I was trying to run the benchmarks on multiple platforms to so I saw one of your project, which is a multi configuration project where you use a matrix to label to run the whatever build in multiple agents. So I was, I was thinking of doing the same thing, but so I have three branches, three benchmarks I want to run. So it's a multi branch project. I'm not sure if if in a multi branch project I can add that configuration matrix. So, is there a combination, is there a project type of a project which I can use which mixes both of them or would I have to use a configuration multi configuration project with a simple pipeline and add my branches and then write some shell steps to run the benchmark Java command to run the benchmarks. How should I do it. So the, the, I think what you would want to do is use a declarative declare or use a pipeline. And we probably want to put it in as a, as a declarative pipeline, and let's use the matrix operator to do it. So that way you don't have to, you don't have to wrestle with the old school thing that I'm using I have those multi config projects because I want to be sure that I don't break compatibility. So not the best way to do it now the best way to do it now is declarative pipeline with matrix. So, so there's a there's a much better way to do it thanks to declarative pipeline. And you can find, you can find documentation about it on Jenkins.io. And I'll do that. Okay. So the second thing I think which we should discuss is the estimator class I've, I've raised your PR for that Fran and Omkar have reviewed it. They've given an initial review to it. So, so would you guys like me to discuss the design of the class or is it something you would, you would first want to review the PR and discover it yourself. And help you guys if I discuss what I've done and what I've thought about it, the experience for the class. So I'd like to hear the brief design design description for me at your insights or your comments can be quite helpful for me as I try to understand it. So, so I tried this the UML diagram. Hang on in Terry J. I'm not sure if this is going to be very helpful, but so the class, the repo estimator class size estimator class is it X it can work in two ways. The first is it has two constructors. The first requires a gate SCM SCM source object, which will be used to analyze if it has a cash dot get directory or not if it does it would calculate the size if it doesn't, it would switch it would, it would try to find an extension which has, which has implemented the extension point we've provided. The second constructor I've added is, so the first constructor limits us to multi branch projects. That is, that is the only place where we use a cash dot get directory we can find a cash directory so the second constructor would just ask for a repo you for the repository URL and would try to find the implementation of the extension point we've created and if it does exist, we would provide the recommendation on what get implementation the plugin should use for that project. So the input can be two things it can be the update SCM source object or repo URL, the output will always be a string which would either be which would either be yet j get or I've chosen none. If I don't want to recommend anything and want to use the default. Get to resolve by the plugin, how that is working I'm going to explain it more detail but this is the basic input and output of the class expectations. So, so I think I should directly show the code a little bit. And then one of the major problems right now we have which Fran has pointed out clearly, and that is something I need to work upon. After this discussion so so the first constructor it asks for the get SCM source so once it was its initialize the class it will. So how it calculates the size is that it I'll show you the method the method word try so we're not locking the cash we're just getting the entry then we're. Then we check if the cash directory if it exists, if we check that if it if it has a dot get directory or not if it does, we would calculate the size by size of directory API and store it in a class member and. And if it if this doesn't happen if we don't have a cache. The second option we have is to use an API. So for that I have created the extension point. The extension point I would like to show to you guys is. Where is the extension point. Yeah, here. The extension point right now is so when I was looking at the documentation of how to create an extension point I saw two ways of making it. One is through the singleton pattern and the second is the descriptor describable pattern. So to be very honest, I am not 100% sure on how the descriptor describable pattern is working singleton pattern I could understand what it was. How I could design I could how I could design the extension point through it. And I'm not sure if the decision of using it was and not using that that pattern is wrong here but what this is this extension point is expecting is is that I provide you the URL of the repository I assume that the implementer has the credentials for the user. And how did I reach to this assumption or to this analysis is that I looked at the github plugin brand source plugin. And I was looking at how I could initialize a client a github client. How are they how have they how they have wrapped the github APIs Java APIs. So I was looking that they either they need the user ID password or they can use a token. So initially I was thinking of passing the credentials from here as well but then I realized that the client there would. They would have the user credentials for the particular if they if the if the project is using that plugin they would also have the credentials. So for me, I think the only information I need to send to them is the repository URL and they would just need to. They would just need to send a get request on the repository URL to get the size through a JSON response from the API. So this is the only method the second method is is where I have the issues right now. So as I was looking at extension points what I could see was extension points in any plugin are made to extend the plugins functionality to other plugins as well. So we basically like I so my reference point was the listener extension point we have in in the get plugin within the get if if I want to be precise it's within get status. We have we have an extension point an extension point called listener. So I kind of model the extension point in a similar way and I can see that this this extension point is meant to provide the capability of listening to some updates. Now my extension point is very is different is actually opposite to this thing what we want is that we are not extending what we want is that we want other plugins output in our class. We don't want we're not sending them we're not extending any capability to them we're actually using their capability to get something for our need. So the issue with this this need is which Fran has pointed out that what I am doing right now is that I am using the extension list. And so I I expect that whatever plugin has implemented the repository size API. I would call the method for the repo URL I have and get the size of the repo. Now the issue with this is that this is a list I was while I was designing. It's actually very it's a huge mistake. While I was designing the extension point I I was only thinking about the GitHub brand source plugin and I never I actually it's a very the mistake is that I didn't think about other plugins which might also implement it and we would have a list of implementations and I don't have any method right now to distinguish which implementation I want to use. So Fran was suggesting suggested he in the PR that there we might want to find a way where we can use the URL to find out what kind of extension class we would want to use. So what I understood from his comment and he may he may clear me right now Fran you can clear me right here. I was what I what I got to know was that if I have a GitHub URL I would I would extract maybe the word GitHub from it and look for the class if through the list I would look for the class. Actually as I'm discussing this I this might not be possible so the part where I'm confused right now is how do I how do I clearly get to know which plugin classes are implementing this API. What I could find a find from yeah yes ma. Actually Fran Fran has much deeper experiences of Fran if you were going to say anything I will defer to you. You know what I what I wanted to say is a rich up a thing in a station extension just like in a class that is annotated in a special in a specific way. And in the moment that the plugin is installed or in the moment that the Jenkins instance is is being started is loaded and is available for any other component that's a component in the Jenkins instance. So a you are calculating the size of the rebel into ways the first one is just using the ticket catcher. Okay but the other one but the other one is just using the API that API is going to be totally dependent on the key system that you have behind you. It's not the same API for github that for kid lap down for the packet or whatever else. So a what I would like you to think about is the way that you say okay. Who's going to provide that API and the way to. A to calculate a site using the API. Each plugin is plugin that is depending on good plugin. So what we have to do is just to a as you have said a provide an abstract class that will be extended by. The other plugins. Those classes in those plugins can be annotated with extension class so we can. At any point in Jenkins we can always read from them in our case because we are going to to say okay give me the full list of reported repository size API classes. And we need. Mechanics to decide a of the full list because if in our Jenkins instance we have the key have plug in the kid lab to beat back it and so on and all of them. Are just sending and giving up and providing us the mechanics to. To discover the the size of the repository using the API. That list will contain all those extensions. So we need the mechanics to say. This kid repo is a kid have rep or so I'm going to filter by. I'm going to filter that list so I can get or or or I discuss the rest of the of the extension point. And I'm getting only the one that is going to give me the API for this a kick a kid have API the same for kid lab and so on. So what do you have doing here is just to creating a point something where the rest of the where the providers and we can also can have just some. Generic way to calculate that I don't know if it's possible or not maybe it's just doing a clone in a temporary file. Just as a default implementation. But what I mean is that you know what is the. The URL where you want to connect and I say the URL because it's probably the easiest. In field that we have just to determine to determine which is our kid system okay but if we have another another way. It's totally fine. So we have to determine we have to specify to discover which is the. System that we have behind our API just to filter in that list of in that extension list, which is the extension which will provide us the correct method. To calculate that site. I don't know if my my safe from the suit. It's clear to me. Yeah, I guess. Yes. Yes. One other thing I'd say to is that you also have to remember that people can locally install like a get lab or get hub enterprise. So you'll have arbitrary rules as well. So those plugins may need to provide what are registered URLs potentially or somehow you need to understand like for this repo, which plugin is configured to. To handle this, which I'm not sure if that second thing is possible, but perhaps the other plugins going to need to tell you. What URLs. Are configured for that plugin. Okay. Yes. Yes, what are you saying. Could we delegate the responsibility to decide if a particular URL can be handled or not to the extension implementer and make part of the contract be that if they can't implement it they return a negative one. Or they return a nonsense value like zero. And then you don't have the responsibility to decide shall I shall I call you, you rather tell them I promise I'm going to call you a lot. You need to exit quickly. If you can't handle this thing. And you need to accept that you may get you will receive things that you cannot handle. So I solemnly promise to send the get GitHub URL to the bitbuck and bit bucket endpoint to the bit bucket extension and to the giddy extension and to the get lab extension they're all going to get it and they must all return a negative one if they don't intend to process it. Would that work so that you don't have to put any logic at this layer to to decide should should the callers handle this, should I call them. Yeah, it's almost a matter of pattern. Yes, and that's only just to add to add a new or a yes, a new method in your after class that has to be implemented by the bind implementers. So I think that Marcus has pointed the the easiest ways to to fill that mechanism so deciding which is the implementer of the of the API which you know. So if we implement. So if we add that method in our contract that means that I would only get from the list I would only get the valid implementation and nothing else. So I would know. So would still would I have to keep a check to to see if any other implementation has not. No, so that wouldn't happen right so if so my so that even if we have that contract and they return a minus one let's say. What issue we might have is that so we use the extension list to get the extensions which are instantiated in the Jenkins environment. So if any, if any provider, let's say five providers have implemented the extension point. If I call the if I call the get extension list function API, it would give me the list. Okay, but I would have since I have a method which which might be a Boolean or might be let's say it returns a Boolean false. If the URL is not if the URL is GitHub but it's it's been implemented by bid bucket that says I cannot implement this. So let's just return false or minus one zero whatever we're returning for the size. So I would just keep it I would just before calling for the size for the method which is trying to find out the size I can just keep a check. Okay, if it's if this if if the let's say whatever the contract the method is, if it's false or if it's minus one, I will not call for the size for that particular instance taken from the list. Is that what we would do that that feels more complicated than how I was envisioning was you call every implementation, ask their get size of repository with the repo URL. If they return you a minus one you know to ignore them. If they're not responsible to decide in their get size of repository URL, or get size of repository method. Should they actually ask the remote system or do they look at the URL or they look at some other, some other thing they know and say this is nothing I can process. Okay. I may be off. It just seems like it's, it's a place where we can ask the question and rely on and tell the tell them as part of the contract. You're going to get asked questions for things that aren't yours. Your responsibility is to return minus one as quickly as you reasonably can. Yeah, that's that's, I think that that can that's easier for him to implement for us. And maybe minus one may be a poor choice does, I don't think that Java has a concept of an unsigned long so I guess minus one is fine but a repository size of either zero or less than zero. Both of those are nonsense right neither of those are useful to a repository size estimation. Yes. Okay. Okay, so I love, I like that to our contract and I love update. Okay. So that's how we're going to do it. The last thing I think for this class is once so how do we decide what implementation we have to use. I just have a simple constant, which right now I have. So I assume that every size I'm going to get is in kbs. That is also something I am, I might need to specify. Not sure how do I specify that in the extension point. Except writing a Java doc. I am not sure. Yes. Why, why kbs you've got a long it's a 64 bit quantity. There, there isn't a file that I know of that's ever going to overrun. I hope nobody tries to do a terabyte size get repository. The reason for kbs mark is that first that the file, the API I used to estimate the cache it returns the size in kbs. Oh, okay. Good, good choice. Yeah. And the second is the, the API is a GitHub or Git lab. So I've tested it with GitHub. They also provided in kbs. Perfect. That is I yeah. So it's five mb right now the switches five mb right now to be more precise on what the switch might be. I might, I might run a lot of tests for this particular reason to to get closer to the point where the nature of J gates performance is that point which we found out in phase one through the results. So right now I've taken it as five mb. So what happens is if it's greater than five mb, we recommend get. And if it's not, we recommend J get. Another thing which was which I considered was that even if I recommend get, I don't know if get is installed in the system or not in the particular node I'm running to. So I used I borrowed the resolve get to implement the logic, which is in get you tell. So what I do is once I decide from my side, what implementation I should use, I run it through the get you tell dot resolve. And I've done it here determined get to. So, so it basically uses that resolve the tool method and if it has get it will recommend get if it doesn't, it would. So if it doesn't, it would go for the default installation. So one question I had here was while I wrote a unit test for this particular for just the cash. So if I have a cash, would I get the right tool or not. So while I was doing that, the, so the, the recommendation from my class should have been J get. Before resolving the get tool before checking if the system has it or not. It was J get but once I, I passed it through this method. It returned get tool to me so I actually was not get get to me sorry, and I was not sure why is it doing that so as I was trying to debug it. It looks for the descriptor implementation for the particular tool, which, which we are trying to as the parameter we have passed here. So it could not find J get and hence it went for the default installation is why would that happen I'm not sure because J is something which is pre is always installed in our would be installed because it comes within the plugin. So that's something maybe once you look at the PR and So I was running the test and I was getting that so I was not sure why that was happening so I thought should tell you Yeah, good question. I don't know the answer. There's some oddity in the constructor of the get of the get SCM that have surprised me in the past so you may be exploring areas that that will have to learn more. Okay, so. And this, this does check the system get like it doesn't only rely on Jenkins installing it. Justin, I'm actually not sure about it I as far as I know it checks. The agent of the node wherever it is it checks if they get installation is present or not. So there's a there's a there's a way to install tools in Jenkins. You can have Jenkins manager, your tools for you tell what binary you want and what version you want stuff like that and I'll make sure that it's installed. But I've also seen a lot of people not use that. So if it's like actually doing a check on the system, then that would work but if it's not and it's relying on people using the get tool or the installation of tools via Jenkins, that's only going to cover partial cases. So just something to look at. Okay, I will look into that. The reason why I did not was that I assume that since this is being already used with the existing functionality it is used to resolve to get implementation I assume that this would look out for every case. So I did not bend deep into how this is resolving or how it's actually finding the executable. I look into it. Yeah, I'm not sure. Maybe these guys know. Sorry. I think, Rishabh, your, your assumption is a good assumption and if, if this method is flawed. I think we handle that separately. You're, I think you made a very good assumption to think that if this method is not doing the right thing. We should solve that as a separate separate solution. Yeah, yeah. Because this thing has the node. It has a string name for the proposed get tool. It has the environment variables. So it's got all the things it could, it could potentially use to answer the questions Justin Justin noted. If it fails to do that. That seems like a bug that we need to solve separately. Yeah, because I mentioned, you're using this in other places to, to invoke the right get. Yeah. Okay. Cool. No, that's fair. So, so I think this is what is happening with the class and the biggest problem right now we what we discuss is the biggest problem and that is something I'm going to handle right now. Apart from this. So my next concern with the class was that how do I actually so I wanted to test it in a real case. I wanted to build a real case scenario with this class and to do that. So I know that I can rely on the cash, not 100% rely on it, but I know that the cash it's I've written unit tests for for cases where if I if I don't have a cash repository or if I have a cash repository, how the class would work. I don't have cases that I've actually never tested the class with the extension. So, so with respect to testing the extension function and the second heuristic before. So I've seen that we have an annotation called test execution test extension, which actually allows us to implement an extension just for the test. So the concern, the concern with that approach is I have is that I would have to so if I'm working the way get branch source plugin would want to work they would. So they create a GitHub client. So I would have to add a lot of depend the dependencies they are using the libraries that I would have to shift all of that for the test only or I could just use an HTTP client which would just perform a get request with credentials or without credentials that would not have a GitHub client. It would just be an HTTP client performing a get request on the particular repository URL that is how I could test it within get plugin. I was actually thinking to try to go to get branch source plugin and implemented just for my local system and then try to work that out, install the plugin, create a project and then see if my system is able to my implementation is able to use the extension and the implementation provided by the extension and get the size. So which so for so my the purpose of the whole thing is that for the demo I was thinking that I if I could do this, I could show the this class working for a cat for a cash repository how we're going to estimate the size and maybe when we go to get SCM for a single pipeline when we're just checking out the project. There also I can use this class how I, if we have an implemented API, we would not have to call the get SCM source constructor we could call we could just use the repository URL to estimate the size and give a recommendation at that level as well. So, so to do that I need to either I need to go to get Transource plugin and create an implementation. So should I work on that and actually see if this implementation would work or not extension points. So I, I, I like very much the idea of doing a concrete implementation in another plugin. I think that's a that's a very healthy thing to do. However, you did describe that the extension point test inside may help you diagnose more quickly than using a second plugin. Back to your so so yes I think it's great to use the separate plugin as a as a that's that's where the real implementation has to be anyway. So that makes makes a lot of sense, but in your suggestion on how to test inside this plug in the test doesn't have to actually make a call to anything. Like the extension points you implemented in the test could just do something like, given a particular URL, always return this size or given this other URL, because it's inside your test you can, you can do all sorts of things that avoid any calls to the outside that keep things very, very simple and say, if I see it, if I see a repository that ends with the number five I'll always return five. If I see those kinds of tricks, because it's a test. Yes, Mark, sorry. I was just saying that Fran suggested that I can mock the HTTP response, whatever response I need from the API, and I can test it. So, so yeah, that will be the quickest ways I'm going to do that first to after I improve update the contract, the implementation and the extension pointer. And for the demo, I'm thinking that I can, I can make a quick implementation there. I actually, I started a discussion thread on the Jenkins dev group to just know from where I can start where what would be the best place to implement the extension point I'm providing because that would be easier for me to figure out where I could do that. So if I, if I get the response there, then it's good. If I don't, then should I, is this, is it okay if I contact the repository maintainers? I saw that I'm actually not sure of the name. I have seen the GitHub handle it a bit wise man. Yes, Liam, Liam Newman. You can certainly, you can certainly ask Liam questions. He's very, very willing. He'll respond as time allows. So, so I'll ask him where I could do this. And so that will be quicker for me to actually implement it and then use it for our demo purposes, and actually, for our further analysis. So, so I think this is it for the class. I actually have a lot more things to share but I think the time has ended, either we could do it on Friday. On Friday, I would have, so I have some new benchmark results Omkar was very helpful with creating different repositories with different kind of parameters we needed. And we have some results from those analysis. I also wanted a result from different platforms. I was looking at your instance and I was thinking to run that, but I could not, I could not do it. So I don't have that right now. So if you guys are comfortable, we could share the results, I could share the results right now, whatever I have. So, did you check why it was failing on Windows? Yes, Omkar, I actually, if you could see when you raise the concern, the next commit I committed. So it was failing because I was, I was expecting something wrong from the assertion. I was not the windows returns get dot exe exe and I was expecting get. So I changed that. That is why it was happening. I'm sorry I did not directly answer your question there. I'm sorry. Okay. Okay. So if you guys want I can share the results right now. If you'd like I could share them on Friday. What would you guys prefer? Let me double check my calendar. Good question. I think, I think I may actually have other things that are colliding on my calendar. Yeah, I'm, I'm supposed to be in another meeting right now. So it's probably best if it's okay with you if we were to defer it until Friday. It is okay with me. I actually think the results we I have they don't not sure if we could use them right now to get something actionable, but nevertheless we need to discuss them so we can discuss them on Friday. Okay. Okay. The last thing with Fran and so we were discussing that we we could. So we could in whatever the implementation we have discussed the update on the extension. So Fran, would you like me to do it first and then you would review it. So I inferred I'm not sure if I inferred correctly what you were saying in the get get a channel was that we could do it together. I mean, what I mean is that, for example, tomorrow morning, because I'm in Central European times. We can overlap several hours. So at anything that you can try, we can be reviewing reviewing almost live because I can jump into the into a kid have and see, okay, this is what I mean. I was thinking more about this other thing. However, I put a couple of comments during this meeting, just to try to make clear what Mark Justin and I was saying about having the how to filter about how to filter the extension list, using a method in the contract that the other implementers have to develop. Okay, so have a look at that. And if you have any question regarding the data approach. Let us know in guitar and as I say, tomorrow morning is we can overlap more time so we can just doing almost life. Sure, that'll be great. I'll be available throughout the morning and so we could do that. Yeah. And I'll try to do whatever we've discussed today. So that'll be better for us. First, I try to have a look at that thing how to how to do it and tomorrow we can discuss that with more a when you have spent more time thinking about how to do it with more context. Okay. Okay, that'd be great. Okay. I think that's it for the meeting. Thank you. Thank you everyone. Bye. Thanks.