« first day (1967 days earlier)      last day (1213 days later) » 
00:00 - 20:0020:00 - 00:00

12:00 AM
RELOAD!
[rubberduck-vba/Rubberduck] 5 commits. 4 opened issues. 1 closed issue. 10 issue comments. 8087 additions. 5294 deletions.
 
I'm using a converter at the very least.
 
[Minesweeper] Games Played: 38, Bombs Used: 27, Moves Performed: 5087, New Users: 9
 
Home time.</iven>
 
 
1 hour later…
1:05 AM
Achievement unlocked:
Looks OK to me.
 
1:29 AM
-17 projects huh
 
it's actually 17 projects and -17 anti-projects.
w00t, no more stupid useless warnings
only 42 warnings
 
That commit message...
 
1:50 AM
[rubberduck-vba/Rubberduck] build for commit 67128e68 on unknown branch: AppVeyor build succeeded
 
Lo and behold! I have found it and it shall be called 'Mount Stupid'.
:hangs-head: I now feel like I'm just past the relative minimum and beginning my ascent again. :+1: and many thanks to this pond.
 
@IvenBach you're way past Mt.Stupid
 
hm - I always thought that Dunning-Kreger effect meant that people stayed oblivious even for long time.
This chart implies that as they gain experience, they eventually became stupid again? Doesn't seem right?
(apologies for being that guy. I'm such fun at parties, ain't I?)
 
@this the scale says "confidence", not "stupidity" ;-)
 
@this Does staying oblivious mean they aren't gaining experience?
 
1:56 AM
100% confident + little experience => Mt. Stupid
 
See, it depends on how you define experience
10 years doing same thing again ≠ 10 years worth of experience
 
noob to expert?
 
but the chart doesn't make that clear.
 
to be fair I was about 10 years into VBA when I realized I knew nothing at all
xp != knowledge
 
FML It took me 15-20...

We're all idiots

Aug 22 at 19:34, 15 minutes total – 24 messages, 6 users, 0 stars

Bookmarked Aug 22 at 19:52 by Mathieu Guindon

 
1:58 AM
Exactly. Yet, with that chart,.... If we substitute "experience" with "knowledge", it still doesn't make sense....
@IvenBach drools
 
There's just too much to learn and not enough time for it all.
 
^
 
Pick your task and adjust for how much available time there is.
 
Either way I look at that graph as experience != time spent doing something.
I know so little of nothing that I'm willing to admit it.
 
2:02 AM
looks like the build shaved off 400 lines. Not too shabby.
now I probably should write something about the build process....
 
2 bits for that shave?
 
how did that ditty go again.
ah, Shave and a haircut two bits
 
[rubberduck-vba/Rubberduck] build for commit 1f60dcee on unknown branch: AppVeyor build failed
BUILD FAILURE!
 
See, Duga does not like corny tunes.
 
2:06 AM
@Duga I don't think this is a legit failure.
@MathieuGuindon mind kicking AV?
@IvenBach yes, I love that episode
 
Episode? You mean Movie. That was a favorite of mine.
 
#word. I meant scene
as, a part of the movie
 
> My uncle Thumper had a problem with his probate and he had to take these really big pills.
 
and while we're at it --- if the barber shaves only the men who do not shave themselves, and all men who do not shave themselves are shaven by the barber, who shaves the barber?
 
The town has 2 barbers who shave each other.
 
2:11 AM
Would the 2 barbers be the barber if there were 2?
 
@this kicked
 
thanks
 
2:23 AM
[rubberduck-vba/Rubberduck] build for commit 1f60dcee on unknown branch: AppVeyor build succeeded
 
now that's more like it.
 
AV is like these old cathodic TVs that would only work after you slap 'em lol
 
IKR?
 
3:17 AM
Well here's an interesting nugget. I hail from the motherland of Germany. Way back when in 1790 one of my ancestors was born there.
So much paperwork to still go through.
 
uh, I thought Germany is the fatherland. Russia is the motherland?
(please don't ask me where the sonland or daughterland are....)
 
You'd be correct with motherland since this is my moms lineage.
 
le sigh why you gonna be slippery like eel, mister VBA?
everyone knows to not fiddle with their pointers but you? you seems to want to change it every time I read it. WHY.
 
3:42 AM
LOL. Newpaper clipping of my old man "Uncooperative hippie taken into custody".
 
3:55 AM
> This is worse than I thought.

It seems that `lpvarValue` may change value when we read it. Sometime it does actually provide a null pointer but other times it provides a random value. However it is consistently in the high-order half of the value. Since I don't have anything better, the solution seems to be apply a bitmask on the high-order half for 64-bit Office.
 
4:34 AM
> Is rubberduck-vba is IDE alternate to VB6 IDE? If yes then whether it is Windows 10 supported? I have a tough time to install VB6 on Windows 10 and can you help me to find a way to run VB6 code on Windows 10
> Closes #5241

Prevent crashing on 64-bit systems due to VBA putting random values in the `lpvarValue`, confounding the `IntPtr.Zero` check. There is no apparent pattern to why it's doing it but it is consistently in the high 32-bit part, so we can look at the low 32-bit and determine if it's really a pointer or not.

Note: The Com projects are not enabled still.

Additionally fixes missing XML tags. 2 Warnings weeded.
 
4:51 AM
[rubberduck-vba/Rubberduck] build for commit 20f0e15d on unknown branch: AppVeyor build succeeded
> Unfortunately, no. It is an add-in to both VB6 and VBA. Maybe this will help?

http://blog.danbrust.net/2015/09/14/installing-visual-basic-studio-6-on-windows-10/#.XbJ-3YpOmhA
 
@Duga blargh will edit the PR title
 
> The problem looks to me to be in RDs code....

https://github.com/rubberduck-vba/Rubberduck/blob/f606675a9ee8e06474d2b41efcd175882440b812/Rubberduck.VBEEditor/ComManagement/TypeLibs/TypeInfoConstantsCollection.cs#L50

It should be checking the varkind for VAR_CONST, not checking the lpvarValue pointer against IntPtr.Zero.

When the VARDESC structure gets created (by OLE or VBA or whatever), only oInst or lparValue will be set. On 32-bit the lparValue and oInst overlap and thus occupy th
> The problem looks to me to be in RDs code....

https://github.com/rubberduck-vba/Rubberduck/blob/d53d42e1d508305d75704cb8ca688493179146fc/Rubberduck.Parsing/ComReflection/ComModule.cs#L61

It should be checking the varkind for VAR_CONST, not checking the lpvarValue pointer against IntPtr.Zero.

When the VARDESC structure gets created (by OLE or VBA or whatever), only oInst or lparValue will be set. On 32-bit the lparValue and oInst overlap and thus occupy the same memory area, and so wr
> Thanks for the technical explanation on why the random values in 64 bit. That reassures me that the fix was correct.

Yes, you would think we would get VAR_CONST for constants. Unfortunately, as documented in the code, it is not the case. VBA simply call all constants and types VAR_STATIC, thus the workaround above.
> Ah yes, I vaguely remember that.

Your fix on the VBA side does not address the ComModule incorrect lpvarValue pointer check. The OLE provided versions of VARDESC might be zero-initialized... but who knows if you're just being lucky.
 
 
2 hours later…
7:25 AM
> In general I am mostly in favour of ULPs as they seem the most correct in addressing the specific issue of floating point behaviour due to limited precision. On the other hand though using epsilons is useful for when you only expect your number to be correct to a certain precision. For example if you are implementing a numeric integration algorithm and want to test it with a known integral up to a certain precision.

In more general terms the reason I want an assert for these things is becau
 
 
2 hours later…
9:05 AM
> Considering that the basic premise of this issue is (unfortunately) incorrect, I'm closing this issue as not applicable. Thanks!
 
10:05 AM
> for the record: I can now try to run a build on my linux machine. Understandably it utterly fails because we're still targeting .NETFramework, but this is going to go a long way to enable development on other platforms, possibly allowing us to reuse parts of Rubberduck in something like a VSCode plugin or a cross-platform standalone editor :)
 
~waves @IanCook
 
10:41 AM
 
 
2 hours later…
12:44 PM
> Just one question - is it conceivable that we would be handed a valid pointer that exists only in the high half of the 64-bit address space?

We could use `ReadStructureSafe` but that's going slow down things a bit.
 
@this ouch!
 
@Duga Nice. The one to get it building on Core will be its own PR as that will be a bit more difficult.
 
@this I'm very confused by that, too.
 
12:59 PM
@FreeMan TBH, I need to stop expecting logical and rational behavior from VBIDE. ;-)
 
> Yes, there's no guarantee the lower 32-bits being zero gives an invalid address.

Using ReadStructureSafe might help, but there's also no guarantee that the full 64-bit address [with an invalid upper half] would not point to _something else_ in memory and thus treating it as a Variant might still cause problems further down the line. For example, you might end up de-referencing an invalid BSTR inside a bad Variant picked up that way, and that could bring down the host.

But if varkind is
 
@this Is -17 anti-projects the same as 17 projects, or is it more like negative infinity?
@this It got rather philosophical last night while I was busy attempting to lay carpet...
 
@FreeMan need them balanced. If they don't balance, you end up annihilating the duck.
 
TBH, I need to stop expecting logical and rational behavior from VBIDE Microsoft. ;-)
@this ^ FTFY
@this and if you annihilate the duck you don't even get duck soup, and that's bad!
 
lol
 
1:11 PM
> I can't remember off the top off my head whether both of the VBA typeinfos had that same flaw with the varkind member not being set properly. It might be worth checking if the alternative ITypeInfo versions have it set correctly.
> I can't remember off the top off my head whether both versions of the VBA ITypeInfo had that same flaw with the varkind member not being set properly. It might be worth checking if the alternative ITypeInfo versions have it set correctly.
> Good idea - I'll check when I have a chance. Thanks!
 
2:08 PM
is it possible to define a foreign key on TableB that must exist in TableA.Col1 or TableA.Col2?
 
2:21 PM
nope. you have a problem on your hand.
 
Figured not. Guess I'll keep the FK relationship on the "official" QuestionID column (which has the question as provided in the data coming to me), and use the AltQuestionID column (the "friendly" name I gave the column in the existing table) as a reference to the "Official" name.
Shouldn't be an ongoing issue - Only time I'll need AltQuestionID for code execution purposes is when I'm converting the existing flat table to the normalized structure.
Ongoing, I'll be receiving QuestionID in the data and will look it up there.
 
you could have 2 FKs, though, and allow AltQuestionID to be null
 
2:39 PM
ah, that could work. thanks!
 
just feel bad everytime you use it, mmkay?
;-)
 
... :/
2 FKs not recommended?
 
just to be clear that was fastidious.
 
at the moment, there are no SQL enforced FK references anywhere in my DB schema - it's all code based and "Don't do that!".
 
but yes, it's not optimal design to have 2 columns referencing same FK as that makes everything unnecessarily complicated
but you're dealing with 2-generation scenario, so it's understandable
 
2:48 PM
fastidious or facetious?
 
What usually is the worst is that when the old generation should be done with, nobody come and clean those up then comes the 3rd generation...
Blargh. #words
 
:)
 
Facetious is what I mean. I be very good at conflagration.
 
<-- is quite happy that the only things the pond knows about his designs are what he shares publicly.
much of what I've done over the years would make some of y'all shudder I'm sure
 
I think that's true for anyone else.
I still feel a bit sad when I open my projects from last year.
 
2:50 PM
@this I'm in this situation precisely because I didn't properly normalize the table the first time.
 
3:41 PM
Productivity this morning.
Anyone with a little WPF knowledge available? Trying to rubberduck what might be the grouping header issue.
When I bind to the added property QualifiedNameAndComponentType in the XAML file it works.
Replacing that with <DataGridTextColumn Header="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=CodeInspectionResults_Location}" Binding="{Binding QualifiedSelection, Converter={StaticResource QualifiedSelectionConverter}}" /> the header is blank but all the cell locations are correct.
 
3:59 PM
@this you be good at massive fires?
 
@IvenBach me no speakee WTF. what are you trying to do?
@FreeMan was wondering if anyone'd catch that deliberative conflation. ;-)
 
Attempting to add the ComponentType for the inspection. IE what it is ClassModule, StandardModule, Worksheet, Workbook, etc...
 
4:15 PM
ok, and you say the cell location is correct -- but are they also blank?
 
16 hours ago, by IvenBach
user image
 
sorry i might be dense here but the 2nd image is you sorting by type?
why is it "barfs"?
 
The Grouping for the top half is not by group. The grouping header displays correct.
The lower half is grouped by location and the grouping header is not displaying correctly.
 
@this took me a second hour
 
Each result is itself displaying correct Document ClassModule etc...
 
4:20 PM
i feel I'm missing something obvious because you keep referring to a header but I don't see a header for the component type; only for issue, type, or location.
 
Grouping header is Rubberduck.Opportunities (18) for the top half and (270) for the lower.
 
doh
 
Is my terminology correct?
 
so you're thikning that there should be ClassModule, Document grouping header
yes it is - it's just me being a Captain Derp
 
It should state the location when it's grouped by location.
When I use the property I added, QualifiedSelection.QualifiedName, it works. The image above is using the converter to separate the UI logic which is causing the location to not display. FooBar (##) should be what shows for each group in the lower half. Instead it only shows the count as it considers everything located in a null group?
 
4:28 PM
i don't know how groupinggrid provides the grouing header
it's not obvious from xaml alone
i see it binds to the Results
if Results is grouped, that might be why
 
Nor do I. Still trying to figure that out.
 
look at the contents of Results
(for other grouping i mean)
compare that to the type
 
They should all be InspectionResults regardless of how they are grouped.
 
if it's a Grouping<InspectionResult>, then it's not an InspectionResult
 
Pulled into meeting. Will check after.
^^ that could be it then.
 
4:37 PM
basically the header should contain a string representing the grouping key
 
To see how the headers are generated, you should look into github.com/rubberduck-vba/Rubberduck/blob/next/Rubberduck.Core/…
Anyway, why did you drop the mode specifier?
 
Mode specifier?
If you're referring to the label in the grouping header that's what I'm trying to figure out. Best I can understand it shouldn't have stopped displaying.
 
                        <Expander.Header>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Margin="4"
									VerticalAlignment="Center"
									Text="{Binding Name}"
									FontWeight="Bold"
									TextWrapping="NoWrap"/>
the text binds to a Name property
(and that whitespace could use a couple of keystrokes ;-)
 
What's the DataContext for the GroupingGrid? Understanding that will help me work out the binding problem with Text="{Binding Name}".
 
pretty sure htat's a control iwth its own xaml
 
4:52 PM
the context would be inherited from whatever view is using the groupinggrid control
 
look under UI\Controls
 
In the inheritance hierarchy FrameworkElement.Name is the only conclusion I can come to.
 
the other textblock binds to ShowGroupingItemCount, so.. I'd search for "ShowGroupingItemCount" and see where that takes me
ok found it, it's a DP of the grouping grid control itself
 
DP = DependencyProperty?
 
yeah
it wouldn't kill to have an explicit Source in these bindings
 
yes. that's what the textblock text is binding to for the item count
now, where the Name is coming from....
 
DataGridColumnHeadersPresenter : ItemsControl -> Control -> FrameworkElement.Name is what I've understood.
 
probably not
 
where -> Indicates an additional inheritance relationship.
 
and how would a FrameworkElement.Name ever be the name of an inspection?
 
4:58 PM
Right...
Working with stuff I don't fully understand again. Learning is hard this way.
 
there's a GroupDescription involved, the Name is the GroupDescription's name
 
@IvenBach The line you referred to has Mode=OneTime and your replacement does not.
 
private static readonly Dictionary<InspectionResultGrouping, PropertyGroupDescription> GroupDescriptions = new Dictionary<InspectionResultGrouping, PropertyGroupDescription>
{
    { InspectionResultGrouping.Type, new PropertyGroupDescription("Inspection", new InspectionTypeConverter()) },
    { InspectionResultGrouping.Name, new PropertyGroupDescription("Inspection.Name") },
    { InspectionResultGrouping.Location, new PropertyGroupDescription("QualifiedSelection.QualifiedName") },
    { InspectionResultGrouping.Severity, new PropertyGroupDescription("Inspection.Severity") }
 
I guess you should just change the entry for location in the view model and pass the converter as second parameter to the constructor.
 
I'm a retard.
github.com/IvenBach/Rubberduck/blob/… is accessing the non-existant property... This confirms my idiocy.
 
5:08 PM
no, this confirms you've found the problem and know how to fix it :)
 
The fix is to keep me away from the code base. Need to revert it to what it originally was.
So this is how dev's work? Realize they did something stupid in an attempt to make and update and call it "learning".
 
> The above examples also show that the American style places commas and periods inside the quotation marks, even if they are not in the original material. British style (more sensibly) places unquoted periods and commas outside the quotation marks. For all other punctuation, the British and American styles are in agreement: unless the punctuation is part of the quoted material, it goes outside the quotation marks.
TIL
US English is definitely twitch-inducing
 
^ That's a pet peeve of mine.
@MathieuGuindon You and me both.
English needs to also include ¿ as a precedent mark for question sentences. ¿You realize that I'm an idiot? is clear it's a question.
 
Another question regarding the location header. Doesn't the converter only use the information from the qualified name?
In you exame it seems to take a qualified selection nonetheless.
 
5:25 PM
It's binding to the QualifiedSelection. The converter itself is using the QualifiedName property and it's subsequent ComponentType property to return the location along with type.
Didn't realize that while making it work.
 
¿Is water wet?
 
5:45 PM
> A table can reference a maximum of 253 other tables and columns as foreign keys (outgoing references).
O_O that's a lot o' references!!!
CONSTRAINT FK_TempSales_SalesReason FOREIGN KEY (TempID)
        REFERENCES Sales.SalesReason (SalesReasonID)
        ON DELETE CASCADE
        ON UPDATE CASCADE
Just to be sure I understand 100%, the ON ... CASCADE means that if I delete a row from Sales.SalesReason, then any reference in this table that references that row will also be deleted. Correct?
If I do not specify the ON ... CASCADE does that means that the deletion of the row in Sales.SalesReason will be blocked because there are FK dependencies on it?
Or does that just mean that the FK references are now broken?
 
I personally prefer using FK constraints to prevent such cascading deletions, but YMMV
@FreeMan FK refs can't be broken :)
 
therefore
7 mins ago, by FreeMan
If I do not specify the ON ... CASCADE does that means that the deletion of the row in Sales.SalesReason will be blocked because there are FK dependencies on it?
is true
 
That is what I thought. I just wanted to be sure.
 
also if your table has 253 FKs, ...you're doing it wrong
 
5:59 PM
hence the googlie eyes
Just because you can, doesn't mean you should
 
reminds me of that tweet from one of the devs on the C# team... something about how many ctor arguments you can have.. a ridiculous limit that some code apparently broke
 
O_o yikes...
@FreeMan applies to so much more than trips to Pep Boys...
 
@this design question: I have a Windows Service that runs a timer that ticks every 15 minutes. on tick, I open a db connection, fetch a handful of records, and then proceed to spawn asynchronous REST API requests. Problem is, it's sending a lot of requests, all on different threads, and the server-side "dripping bucket" throttling is busting, so at one point I start blowing up.
The throttle info is in the response header and I'm collecting it, but Thread.Sleep would be useless because the other threads would still be hammering the API
so...
any idea how to go about throttling this?
 
fetch 1/3 every 5 minutes?
 
not going to work
 
6:06 PM
Build a queue of requests and have a limited number of threads process all the requests?
 
> Hi,

I see there have been some open issues with Rubberduck and Solidworks, if you need someone to do some testing I would be happy to help. I currently am running version 2019 and should be upgrading to 2020 in the near future.

I have just loaded Rubberduck version 2.4.1.5086 and have run across some strange behavior with the Refactor. The Refactor menu items are randomly greyed out when right clicking on the same variable name in my VBA code.

Kevin
 
that would be the recommended practice and I'm seriously considering it, but then how do I get the response back to the Task<Response<T>> that made the request?
 
verrrry carefully...
 
hm-hmm
 
I know you didn't ask me, but hey, you're asking the wrong guy...
 
6:32 PM
@MathieuGuindon I think you need to borrow something from Rubberduck's codebase --- I'm thinking that since the throttling applies to all requests, you need to store the the go/stop state in something akin to slimThreadLock object.
Similar to what we do w/ parser suspension.
 
I'm uncertain if we also need to use cancellation so that the thread will stop as soon as it know there's throttling
that might be too rough since that means you need to restart the threads once the bucket drains.
 
the fun part is that the leaky bucket is 40 request per second for one store, and 80 for the other two
 
that's not request's concern. All they need is a bool Go
actually, if that is all, you probably can use Interlocked. Even more simple.
but that means more change in your threading's code as it must check the Go for each step, similar to how the parser checks the cancellation toekn before doing each step of parser.
I think Hosch is your authority, though. He's the one wrote it. I'm just a stuffed shirt. :)
 
I'm going to make such a spaghetti mess...
 
6:36 PM
Even if you're cancelling, you still have to sprinkle the thread w/ cancellation, just like parser, anyway.
 
nah, can't cancel
 
there is no simple "do this but only as long it's OK" implementation
because you basically have to check the shared state at each step
I'dlike to think that if there was such thing, the parser code wouldn't need so many checks on the cancellation token.
 
thinking to add some IRequestThrottler implemenation that every ICursorPaginatedShopifyAsyncRequest<TEndPoint, TEntity> is going to call into, and the throttler can use Task.Delay as needed
 
that'd be run in each task's thread, right?
 
6:40 PM
it just occurred to me just now that the parser could be cleaned up using something like ProceedIfItIsOk(CancellationToken token, List<Action>>)
(besides the craptastic name)
 
was going to say, lol
okay I think I have a workable solution
thanks for rubberducking :)
 
419 I AM A RUBBERDUCK
2
:)
 
a stuffed rubberduck!
 
LOL
 
6:55 PM
> We currently have no testers in SolidWorks so we appreciate the help!

Just to confirm -- the code was already parsed? Most menu items can't be enabled until it has been parsed, and if you dirty the code, then it can't be used (to avoid changing code on a stale parse tree).
 
while it's on my mind - is there any reason why I shouldn't make an extension method in Rubberduck method? I'm considering making one for the lpvarValue so that it's available to Rubberduck.Parsing as well as Ruberduck.VBEEditor
 
7:08 PM
"in Rubberduck method" fails to parse here
if it's in RD.VBEEditor then it's accessible to both assemblies, no?
 
no, Parsing is independent from VBEdito.
"Rubberduck method" s/b "VARDESC type". :(
IDK WTH I was typing there.
 
seems rather low-level for RD.Parsing, no?
 
it has ComReflection stuff
really, that's why I don't think those stuff belong in either.
we need a Rubberduck.ComReflection project
 
eh, we're at what, 21 projects now? what's one more...
 
in fact, lot of stuff of that has little to do with parsing, and not so much with VBEditor (besides as an entry point)
IKR? Let's not worry about it until we get to 99th project, mkay?
Yesterday: no more than one method per class!
Today: no more than one class per project!
 
7:23 PM
Tomorrow: no more than one solution per repository!
ugh. ok so I have a Task<Response<T>> result local variable, and now I'm trying to get this to work:
                Debug.WriteLine($"Shopify API throttle {value}%; delaying 5 seconds.");
                result = Task.Delay(TimeSpan.FromSeconds(5))
                    .ContinueWith(t => task.Invoke());
but that's a Task<Task<Response<T>>>
ooh .Unwrap() seems to do it
 
> Yes, is seems completely random as to when it will work.

For example if I right click on a variable and the refactor is working I can right click on the very same variable with no changes and the menus are greyed out.

I did find that if I switch to another module and try the refactor it works as it should and then I can switch back to the first module and the refactor works then.
 
does this make sense?
        public async Task<Response<T>> ThrottleAsync<T, U>(Func<Task<Response<T>>> task)
            where T : IEndPoint<U>
            where U : class
        {
            Task<Response<T>> result = null;
            var value = _leakyBucketValue / (decimal)_leakyBucketCapacity;
            if (value > 0.9m)
            {
                Debug.WriteLine($"Shopify API throttle {value}%; delaying 30 seconds.");
                result = Task.Delay(TimeSpan.FromSeconds(30))
                    .ContinueWith(t => task.Invoke()).Unwrap();
 
 
> Yes, is seems completely random as to when it will work.

For example if I right click on a variable and the refactor is working I can right click on the very same variable a second time with no changes and the menus are greyed out.

I did find that if I switch to another module and try the refactor it works as it should and then I can switch back to the first module and the refactor works then.
 
try it, mug
 
7:42 PM
ugh, this looks weird
    protected virtual async Task<Response<T>> GetAsync(Uri cursor, string token)
        => await Throttle.ThrottleAsync<T, U>(() => Task.Run(() => Get(cursor, token)));
 
you seem to be on the right track actually..
alternatively you could have some kind of coroutine shenanigans
 
not quite sure how it would work exactly, but it sounds applicable
 
on the bright side there's only 1 class that's overriding GetAsync, so there's that
    protected async override Task<Response<Orders>> GetAsync(Uri cursor, string token)
    {
        var client = RestClient.For<IShopifyOrdersApi>(cursor);
        client.ShopifyAccessToken = token;
        var response = await Throttle.ThrottleAsync<Orders, Order>(() => client.GetFromCursorAsync());
        LogResponseInfo(response);
        return response;
    }
looks legit :)
 
I think the weird part is mainly naming
e.g. Throttle.ThrottleAsync
 
7:47 PM
yeah. wanted Throttler but didn't feel right either
and ThrottleManager wasn't going to happen :)
 
SpeedDial ;)
 
yeah. Manager and Handler are basically "I give up"
 
Snailer is still a candidate
 
Threader.Throttle
 
WeedDealer /s
 
7:48 PM
lol
 
it does deal with http status 420, does it not?
 
Orchestrator.Throttle
LOL
 
any non-200 status gets me a RestEase.ApiException
 
How do you intend to use this?
 
I got it.... RipVanWinkle.Throttle!!
 
7:49 PM
@Vogel612 ironically that would arguably be a better HTTP status code than the "too many requests" code I'm getting
@M.Doerner scraping Shopify, basically
 
"too many requests" and "enhance your calm" are interchangeable
 
I'll make the feature request ...they don't seem to mind making breaking changes :)
 
I meant that in a more concrete way. How do you use the GetAsync method?
 
@MathieuGuindon yikes
 
    public override async Task<IEnumerable<Product>> GetEntitiesAsync()
    {
        var products = await base.GetEntitiesAsync();
        await Task.WhenAll(products.Select(e => ProcessVariantsAsync(e)));
        return products;
    }
and the base class goes:
        public async override Task<IEnumerable<TEntity>> GetEntitiesAsync()
        {
            var lastUpdated = await _timestamps.GetLastUpdatedTimestampAsync(Resource);
            var args = new UpdatableCommandArgs(lastUpdated);

            var items = new List<TEntity>();
            Uri cursor;
            using (var response = await _request.RequestItemsAsync(args))
            {
                var content = response.GetContent();
                items.AddRange(content.Items);
                cursor = response.GetNextPageCursor();
and the _request.RequestItemsAsync method is what's calling this GetAsync
    public async Task<Response<T>> RequestItemsAsync(Uri cursor)
    {
        var info = RequestInfo();
        return await GetAsync(cursor, info.AuthToken);
    }
(there are overloads... thank Shopify for making pagination such a ^$&@% PITA)
 
00:00 - 20:0020:00 - 00:00

« first day (1967 days earlier)      last day (1213 days later) »