Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 2 participants
- 144634 messages
Re: [Pharo-dev] [Pharo-users] A little prototype kernel in 9 methods :)
by Pavel Krivanek
Nice!
Is there any good reason why during cloning you do not set the delegation
too?
-- Pavel
2016-12-11 21:13 GMT+01:00 Stephane Ducasse <stepharo.self(a)gmail.com>:
> I sent the wrong file of course. Here is the chapter :)
>
>
> On Sun, Dec 11, 2016 at 8:52 PM, <serge.stinckwich(a)gmail.com> wrote:
>
>> Great works ! I will add some contents for Actalk chapter.
>>
>> BTW I update a little bit the PolyMath book. There was some sections
>> missing.
>>
>>
>> Envoyé de mon iPhone
>>
>> > Le 11 déc. 2016 à 20:33, stepharong <stepharong(a)free.fr> a écrit :
>> >
>> > Hi guys
>> >
>> > I'm thinking to package some of my language design knowledge in a kind
>> of book. Probably to be used to give a lecture on
>> > OOP languages. I have class-based reflective kernel. This is several
>> years that I was thinking about prototype kernels
>> > and I decided to relax and implement one for fun over the week-end.
>> > I will probably look at mixins, traits, talents, split objects in the
>> future.
>> >
>> > Since I cannot compile the book on jenkins, I join the pdf.
>> >
>> > Stef
>> >
>> > PS: I will finish Pharo by example now and focus on Learning OOP with
>> Pharo.
>> >
>> > --
>> > Using Opera's mail client: http://www.opera.com/mail/
>> > <book.pdf>
>>
>>
>
Dec. 11, 2016
Re: [Pharo-dev] protocol pane "no messages" Re: [Pharo-users] setter method
by Nicolas Passerini
I will add that I doubt that any filetree repository (or at least its
metadata-less versions) repository is capable of remembering an empty
protocol.
2016-12-10 20:27 GMT+01:00 phil(a)highoctane.be <phil(a)highoctane.be>:
> Hi Ben,
>
> Yes and no.
> Because you can add a protocol right away without any method and end up in
> my layout.
>
> Pedantically yours,
> Phil
>
> On Sat, Dec 10, 2016 at 2:17 PM, Ben Coman <btc(a)openinworld.com> wrote:
>
>> Nope. I'll see your pedantic, and raise you...
>>
>> Clicking on "no messages" and adding a method you get...
>> --all--
>> as yet unclassified.
>>
>> So "no protocols" goes away, but there are still no protocols.
>>
>> (pedantic poker, fun for all the family)
>> cheers -ben
>>
>>
>> On Sat, Dec 10, 2016 at 2:56 AM, phil(a)highoctane.be <phil(a)highoctane.be>
>> wrote:
>> > To be pedantic it should be "no protocols" because as soon as you add
>> one,
>> > you get
>> >
>> > --all--
>> > someaddedprotocol
>> >
>> > even if there is no method.
>> >
>> > Phil
>> >
>> > On Fri, Dec 9, 2016 at 7:21 PM, Ben Coman <btc(a)openinworld.com> wrote:
>> >>
>> >> [Forwarded to pharo-dev for side discussion...]
>> >>
>> >> On Sat, Dec 10, 2016 at 2:15 AM, Ben Coman <btc(a)openinworld.com>
>> wrote:
>> >> > On Sat, Dec 10, 2016 at 1:39 AM, Kateryna Aloshkina
>> >> > <aloshkina(a)ucu.edu.ua> wrote:
>> >> >> Hi everybody!
>> >> >>
>> >> >> I've just joined the community:) and have a question
>> >> >> How to write the method count: such that, when invoked on an
>> instance
>> >> >> of
>> >> >> Counter, instance variable is set to the argument given to the
>> message?
>> >> >> so that
>> >> >> Counter new count: 7
>> >> >> would set the value of a new Counter instance to 7
>> >> >> (It is a little exercise from
>> >> >> http://rmod-pharo-mooc.lille.inria.fr/MOOC/Exercises/Exo-Cou
>> nter.pdf)
>> >> >>
>> >> >>
>> >> >> Best wishes,
>> >> >> Kateryna
>> >> >
>> >> > Welcome Kateryna,
>> >> > I hope you are having fun and Pharo changes the way you think about
>> >> > programming.
>> >> >
>> >> > Referring to Figure 1.2, assuming you've already created the class,
>> >> > first make sure you are on the instance-side rather than the
>> class-side
>> >> > of the class such that the class definition in the bottom (code) pane
>> >> > looks just like Figure 1.2. Click the <Class> button to toggle which
>> >> > side you look at.
>> >> >
>> >> > Now in the third (protocols) pane on "no messages"
>> >> > and you will get a method template in the code pane
>> >> >
>> >> > Change... messageSelectorAndArgumentNames
>> >> > to... count:
>> >> >
>> >> > then change.... statements
>> >> > to an assignment to the instance variable.
>> >> > and <Accept> the the code to save & compile the method.
>> >>
>> >> To be pedantic, shouldn't "no messages" actually be "no methods"
>> >> But maybe even better would be... "click for method template" ?
>> >>
>> >> cheers -ben
>> >>
>> >
>>
>>
>
Dec. 11, 2016
Re: [Pharo-dev] [Pharo-users] A little prototype kernel in 9 methods :)
by Stephane Ducasse
I sent the wrong file of course. Here is the chapter :)
On Sun, Dec 11, 2016 at 8:52 PM, <serge.stinckwich(a)gmail.com> wrote:
> Great works ! I will add some contents for Actalk chapter.
>
> BTW I update a little bit the PolyMath book. There was some sections
> missing.
>
>
> Envoyé de mon iPhone
>
> > Le 11 déc. 2016 à 20:33, stepharong <stepharong(a)free.fr> a écrit :
> >
> > Hi guys
> >
> > I'm thinking to package some of my language design knowledge in a kind
> of book. Probably to be used to give a lecture on
> > OOP languages. I have class-based reflective kernel. This is several
> years that I was thinking about prototype kernels
> > and I decided to relax and implement one for fun over the week-end.
> > I will probably look at mixins, traits, talents, split objects in the
> future.
> >
> > Since I cannot compile the book on jenkins, I join the pdf.
> >
> > Stef
> >
> > PS: I will finish Pharo by example now and focus on Learning OOP with
> Pharo.
> >
> > --
> > Using Opera's mail client: http://www.opera.com/mail/
> > <book.pdf>
>
>
Dec. 11, 2016
Re: [Pharo-dev] [Pharo-users] A little prototype kernel in 9 methods :)
by serge.stinckwich@gmail.com
Great works ! I will add some contents for Actalk chapter.
BTW I update a little bit the PolyMath book. There was some sections missing.
Envoyé de mon iPhone
> Le 11 déc. 2016 à 20:33, stepharong <stepharong(a)free.fr> a écrit :
>
> Hi guys
>
> I'm thinking to package some of my language design knowledge in a kind of book. Probably to be used to give a lecture on
> OOP languages. I have class-based reflective kernel. This is several years that I was thinking about prototype kernels
> and I decided to relax and implement one for fun over the week-end.
> I will probably look at mixins, traits, talents, split objects in the future.
>
> Since I cannot compile the book on jenkins, I join the pdf.
>
> Stef
>
> PS: I will finish Pharo by example now and focus on Learning OOP with Pharo.
>
> --
> Using Opera's mail client: http://www.opera.com/mail/
> <book.pdf>
Dec. 11, 2016
A little prototype kernel in 9 methods :)
by stepharong
Hi guys
I'm thinking to package some of my language design knowledge in a kind of
book. Probably to be used to give a lecture on
OOP languages. I have class-based reflective kernel. This is several years
that I was thinking about prototype kernels
and I decided to relax and implement one for fun over the week-end.
I will probably look at mixins, traits, talents, split objects in the
future.
Since I cannot compile the book on jenkins, I join the pdf.
Stef
PS: I will finish Pharo by example now and focus on Learning OOP with
Pharo.
--
Using Opera's mail client: http://www.opera.com/mail/
Dec. 11, 2016
Re: [Pharo-dev] RBPattern matching dynamic array expressions
by Yuriy Tymchuk
Hi John,
thank you for our reply it is really helpful.
Can you please also spend a bit of your time to talk about the âpermissiveness" of the pattern syntax. For example the string '`.head `.@tailâ is parsed into a message node with selector `.@tail and a receiver variable node `.head. To my knowledge this is not a valid syntax as the names that have a dot in the beginning should become matchers for statements. Also for example if you write `#@literal the list marker is not doing anything when combines with the literal pound as far as I know, and some people are confused about this, were the any reason why this is not simply rising a syntax error?
Cheers.
Uko
> On 11 Dec 2016, at 00:46, John Brant <brant(a)refactoryworkers.com> wrote:
>
> On 12/10/2016 02:37 AM, Nicolai Hess wrote:
>
>> Question : how should a pattern with three variables
>> (first/second/third) look like to match the expression
>> { (1@2) . Color red . 3} and assign the (sub)-expressions
>> 1@2
>> Color red
>> 3
>> to the three variables first/second/third ?
>
> The RB was written before the {} array syntax. It appears that are a few bugs in the pattern matching for the arrays. The first is that it needs to reset the isList variable of RBPatternVariableNode when it is part of a dynamic array. You can fix that by adding this to the end of RBPatternVariableNode>>parent: method:
>
> parent isDynamicArray
> ifTrue: [ self isStatement
> ifFalse: [ isList := false ] ]
>
> I think this will make the matching work like what you are expecting. If you want to match multiple statements, you need to add a ".", but if you just have "`@first", it will only match any expression node.
>
> While testing I noticed an error in the RBArrayNode>>match:inContext:. The method doesn't test the lengths of the nodes before sending the #with:do: message. If you try to match two arrays of different sizes, you get an error. This should be changed back to be:
>
> match: aNode inContext: aDictionary
> aNode class = self class
> ifFalse: [ ^ false ].
> ^ self matchList: statements against: aNode statements inContext: aDictionary
>
>
> John Brant
>
Dec. 11, 2016
Re: [Pharo-dev] About traits
by Dale Henrichs
On 12/11/16 12:06 AM, stepharong wrote:
>
> Dale
>
> I missed your remark about traits.
> I think that traits are nice because they act as a kind of static
> macro expansion and really help to get multiple inheritance into
> single one.
>
> Now ideally I would like to have
>
> (I hate so much this google nonUI)
>
> - state with traits with a nice initialization process.
> - Now Pablo did a nice and simple implementation of Talents (dynamic
> traits). I should have a look because if we could unify it and have
> either a trait statically applied to a class (what we have now) and a
> trait being applicable to an instance then it would be really good.
>
>
> Now making the tools traits-aware is much more than just having traits
> in the language.
> - change
> - loading
> - editing
> - overloading when we compile a method that comes from a trait we
> should be able to say that it overrides.....
>
> What we did with the "unification" of traits and classes and the use
> of traits inside the kernel is a mistake (in Squeak andreas if I
> recall made Trait a subclass of classDescription
> and this is not good either - even if he marketed it as a good idea)
> and we will iterated to remove the use of traits from Class and friends.
> Then ideally I would like to iterate over the
> - reflective API (because we should be able to simply access the
> "class" of a compiledMethod from where the traits is coming from or
> where it is installed
> - revisite the implementation because the clause composition.
>
>>
>> I think that the tools should not manipulate traits as classes
>> because traits are not classes.
>> Then doing this we will clarify that the traits and classes must
>> not be polymorphic because they are not.
>>
> Stef,
>
> Thanks for the clarification ... we are open to adding traits to
> GemStone and perhaps we should talk a little bit more about your
> ideas on a "better implementation" ... at this point GemStone 3.5
> would be the target version and that would give us time for
> syncing up the implementation.
>
>
> Sure.
> This can be a good incentive for us to revisit it.
Sounds like a plan...
Dec. 11, 2016
Re: [Pharo-dev] NeoUUIDGenerator>>testTwoSameGenerator - intermittent CI failure
by Sven Van Caekenberghe
> On 11 Dec 2016, at 16:50, Ben Coman <btc(a)openinworld.com> wrote:
>
>
>
> On Sun, Dec 11, 2016 at 7:49 PM, Henrik Nergaard <henrik.nergaard(a)uia.no> wrote:
> >The timing problem might indeed be resolution dependent: 100us is probably to short sometimes.
> Time microsecondClockValue gives the time in microseconds, but it does not guarantee microsecond resolution, on windows the resolution is still in milliseconds.
>
> Useful to know. But regardless of the resolution, the units are still microseconds.
> So the majority of the time you'll assert: 3622 - 3622 < 100
> which passes,
> but other times you'll cross the boundary and you'll assert: ...4622 - ...3622 < 100,
> which fails.
>
> The important question is, what resolution of time is important for UUIDs?
> If 10ms is sufficient, then ...4622 - ...3622 < 10000 easily passes on even the slowest computer..
I don't think it is terribly important, but if #microsecondClockValue has such a bad resolution on Windows (as hendrik showed), that is a general problem. It just not good.
> ----------
> | col |
>
> col := Array new: 30000 streamContents: [ :stream |
> 1 to: 30000 do: [ :x | stream nextPut: Time microsecondClockValue ]
> ].
>
> col asSet "a Set(3658909536504622 3658909536503622 3658909536502622)"'
>
> btw I forgot to mention I'm on 32-bit Linux. So thankfully I get...
> col asSet size "==>16135"
>
> btw2, For a challenge I'm lining up to improve the VM clock "sometime", maybe end of Feb (if it proves within my capability no one else gets to it first).
> https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/36
>
>
>
> -----Original Message-----
> From: Pharo-dev [mailto:pharo-dev-bounces@lists.pharo.org] On Behalf Of Sven Van Caekenberghe
> Sent: Sunday, December 11, 2016 11:56 AM
> To: Pharo Development List <pharo-dev(a)lists.pharo.org>
> Subject: Re: [Pharo-dev] NeoUUIDGenerator>>testTwoSameGenerator - intermittent CI failure
>
> Hi Ben,
>
> Thanks for looking into this, it was bothering me for quite some time ;-)
>
> https://pharo.fogbugz.com/f/cases/19453/NeoUUIDGenerator-testTwoSameGenerat…
>
> Yes, I think the counter roll-over is the problem, stupid of me to to have seen this.
>
> The timing problem might indeed be resolution dependent: 100us is probably to short sometimes.
>
> I will provide a slice with fixes.
>
> Cool. Ping me from the slice.
> cheers -ben
>
>
> Thanks again !
>
> Regards,
>
> Sven
>
> > On 11 Dec 2016, at 09:07, Ben Coman <btc(a)openinworld.com> wrote:
> >
> > For Case [1] I got an unrelated CI failure [2] for
> > NeoUUIDGeneratorTests>>#testTwoSameGenerator
> >
> > Checking this locally by running this a dozen times...
> > 1 to: 1000 do: [:n| last:=n. NeoUUIDGeneratorTests new setUp
> > testTwoSameGenerator ]
> >
> > Two distinct failures are apparent...
> >
> > 1. Takes longer than expected.
> > self assert: (time2 - time1) abs < 100
> > last=1 ==> a time difference of 109
> > last=1 ==> a time difference of 102
> > last=1 ==> a time difference of 155
> > last=1 ==> a time difference of 105
> > Interesting that whenever this happens its on the first iteration.
> >
> > 2. Invalid consecutive ids.
> > self assert: (uuid1 at: 10) + 1 equals: (uuid2 at: 10).
> > last=127 ==> TestFailure: Got 256 instead of 0.
> > last=828 ==> TestFailure: Got 256 instead of 0.
> > last=128 ==> TestFailure: Got 256 instead of 0.
> > last=316 ==> TestFailure: Got 256 instead of 0.
> > Maybe a problem with rollover?
> >
> > So instrumenting a bit:
> > testTwoSameGenerator: n
> > | uuid1 uuid2 consecutiveOk time1 time2 timeOk |
> > ....
> > "same generator, consequetive counters"
> > consecutiveOk := ((uuid1 at: 10) + 1) = (uuid2 at: 10).
> > "same generators, similar clock, within 100 milliseconds"
> > time1 := self timeFromUUID: uuid1.
> > time2 := self timeFromUUID: uuid2.
> > timeOk := (time2 - time1) abs < 100.
> > ( timeOk and: [ consecutiveOk ]) ifFalse: [
> > Transcript cr;
> > show: 'fail n=', (n printPaddedWith: $0 to: 3) ; tab;
> > show: ' time ', ((time2 - time1) printString) , '<100'; tab;
> > show: ' uuid ', (((uuid1 at: 10) + 1) printString, '=', (uuid2 at: 10) printString).
> > ].
> > self assert: consecutiveOk.
> > self assert: timeOk.
> >
> > From playground running...
> > 1 to: 1000 do: [:n|
> > NeoUUIDGeneratorTests new setUp testTwoSameGenerator: n].
> > Transcript crShow: 'x'.
> >
> > Note the 'x' was not output due to one of the consecutiveOk or timeOk asserts triggered each run.
> > fail n=001 time 104<100 uuid 160=160
> > fail n=269 time 2<100 uuid 256=0
> > fail n=001 time 152<100 uuid 166=166
> > fail n=117 time 3<100 uuid 256=0
> > fail n=001 time 123<100 uuid 128=128
> > fail n=278 time 3<100 uuid 256=0
> > fail n=001 time 145<100 uuid 230=230
> > fail n=673 time 1340<100 uuid 141=141
> > fail n=707 time 3<100 uuid 256=0
> > fail n=001 time 132<100 uuid 73=73
> > fail n=001 time 117<100 uuid 206=206
> > fail n=063 time 2<100 uuid 256=0
> > fail n=345 time 3<100 uuid 256=0
> >
> > Now a strange thing is that after commenting out those two asserts for consecutiveOk and timeOk, the fails at n=001 stop happening.
> >
> > fail n=001 time 141<100 uuid 232=232
> > x
> > x
> > fail n=201 time 3<100 uuid 256=0
> > fail n=268 time 3<100 uuid 256=0
> > fail n=359 time 3<100 uuid 256=0
> > fail n=408 time 2<100 uuid 256=0
> > fail n=559 time 3<100 uuid 256=0
> > x
> > fail n=139 time 3<100 uuid 256=0
> > fail n=854 time 7<100 uuid 256=0
> > x
> > fail n=389 time 3<100 uuid 256=0
> > fail n=669 time 3<100 uuid 256=0
> > fail n=876 time 3<100 uuid 256=0
> > fail n=916 time 3<100 uuid 256=0
> > fail n=953 time 2<100 uuid 256=0
> > fail n=954 time 3<100 uuid 256=0
> > x
> > fail n=148 time 3<100 uuid 256=0
> > fail n=741 time 3<100 uuid 256=0
> > x
> > fail n=116 time 2<100 uuid 256=0
> > fail n=480 time 3<100 uuid 256=0
> > x
> >
> > After treating the rollover like this...
> > consecutiveOk := ((uuid1 at: 10) + 1) \\ 256 = (uuid2 at: 10).
> > running the last playground script gives...
> >
> > (Note the n=001 fail reoccurs after waiting a while between running the playground script again.)
> > fail n=001 time 123<100 uuid 110=110
> > x
> > fail n=345 time 1287<100 uuid 24=24
> > fail n=404 time 1313<100 uuid 125=125
> > x
> > x
> > x
> > x
> > x
> > fail n=449 time 1290<100 uuid 24=24
> > x
> > x
> > x
> > x
> > x
> >
> >
> > Thats looking better, so upping to 10000 iterations...
> > fail n=0001 time 151<100 uuid 160=160
> > fail n=2977 time 1437<100 uuid 221=221
> > fail n=5498 time 1454<100 uuid 224=224
> > fail n=9007 time 1351<100 uuid 239=239
> > x
> > fail n=3389 time 1381<100 uuid 223=223
> > fail n=7768 time 1365<100 uuid 82=82
> > fail n=9773 time 1395<100 uuid 164=164
> > x
> > fail n=3325 time 1448<100 uuid 67=67
> > fail n=9930 time 1456<100 uuid 103=103
> > x
> > fail n=0060 time 2914<100 uuid 159=159
> > fail n=1829 time 1438<100 uuid 32=32
> > fail n=7918 time 1436<100 uuid 182=182
> > x
> >
> > So the rollover looks cured.
> >
> > Now adding some more instrumentation to view GC Time and Time To Run
> > and (see attached ST file)
> >
> > 0:00:00:00 TTR 0:00:00:00.001 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00
> > x
> > fail n=0001 time 115<100 uuid 157=157 GCTime 0 TTR 0:00:00:00
> > fail n=0001 time 2<100 uuid 255=0 GCTime 0 TTR 0:00:00:00
> > x
> > fail n=0001 time 111<100 uuid 104=104 GCTime 0 TTR 0
> > x
> > fail n=0001 time 120<100 uuid 204=204 GCTime 0 TTR 0
> > fail n=0001 time 1182<100 uuid 103=103 GCTime 1 TTR 1
> > x
> > x
> > x
> > x
> > x
> > fail n=0001 time 3<100 uuid 255=0 GCTime 0 TTR 0
> > x
> > x
> > fail n=0001 time 1251<100 uuid 253=253 GCTime 2 TTR 1
> > x
> >
> >
> > Now I wonder at the class comment saying...
> > "the first 8 bytes are the *millisecond* clock value"
> > but #clockOn: is using *microsecond* clock.
> > Perhaps "self assert: (time2 - time1) abs < 100"
> > is meant to be 100ms not 100us ??
> >
> > cheers -ben
> >
> > [1] https://pharo.fogbugz.com/f/cases/19438
> > [2]
> > https://ci.inria.fr/pharo/job/Pharo-6.0-Issue-Validator/19471//artifac
> > t/validationReport.html
> > <NeoUUIDGeneratorTests-testTwoSameGenerator.st>
>
>
>
>
Dec. 11, 2016
Re: [Pharo-dev] NeoUUIDGenerator>>testTwoSameGenerator - intermittent CI failure
by Ben Coman
On Sun, Dec 11, 2016 at 7:49 PM, Henrik Nergaard <henrik.nergaard(a)uia.no>
wrote:
> >The timing problem might indeed be resolution dependent: 100us is
> probably to short sometimes.
> Time microsecondClockValue gives the time in microseconds, but it does not
> guarantee microsecond resolution, on windows the resolution is still in
> milliseconds.
>
Useful to know. But regardless of the resolution, the units are still
microseconds.
So the majority of the time you'll assert: 3622 - 3622 < 100
which passes,
but other times you'll cross the boundary and you'll assert: ...4622 -
...3622 < 100,
which fails.
The important question is, what resolution of time is important for UUIDs?
If 10ms is sufficient, then ...4622 - ...3622 < 10000 easily passes on even
the slowest computer..
> ----------
> | col |
>
> col := Array new: 30000 streamContents: [ :stream |
> 1 to: 30000 do: [ :x | stream nextPut: Time microsecondClockValue ]
> ].
>
> col asSet "a Set(3658909536504622 3658909536503622 3658909536502622)"'
>
btw I forgot to mention I'm on 32-bit Linux. So thankfully I get...
col asSet size "==>16135"
btw2, For a challenge I'm lining up to improve the VM clock "sometime",
maybe end of Feb (if it proves within my capability no one else gets to it
first).
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/36
>
> -----Original Message-----
> From: Pharo-dev [mailto:pharo-dev-bounces@lists.pharo.org] On Behalf Of
> Sven Van Caekenberghe
> Sent: Sunday, December 11, 2016 11:56 AM
> To: Pharo Development List <pharo-dev(a)lists.pharo.org>
> Subject: Re: [Pharo-dev] NeoUUIDGenerator>>testTwoSameGenerator -
> intermittent CI failure
>
> Hi Ben,
>
> Thanks for looking into this, it was bothering me for quite some time ;-)
>
> https://pharo.fogbugz.com/f/cases/19453/NeoUUIDGenerator-
> testTwoSameGenerator-intermittent-CI-failure
>
> Yes, I think the counter roll-over is the problem, stupid of me to to have
> seen this.
>
> The timing problem might indeed be resolution dependent: 100us is probably
> to short sometimes.
>
> I will provide a slice with fixes.
>
Cool. Ping me from the slice.
cheers -ben
>
> Thanks again !
>
> Regards,
>
> Sven
>
> > On 11 Dec 2016, at 09:07, Ben Coman <btc(a)openinworld.com> wrote:
> >
> > For Case [1] I got an unrelated CI failure [2] for
> > NeoUUIDGeneratorTests>>#testTwoSameGenerator
> >
> > Checking this locally by running this a dozen times...
> > 1 to: 1000 do: [:n| last:=n. NeoUUIDGeneratorTests new setUp
> > testTwoSameGenerator ]
> >
> > Two distinct failures are apparent...
> >
> > 1. Takes longer than expected.
> > self assert: (time2 - time1) abs < 100
> > last=1 ==> a time difference of 109
> > last=1 ==> a time difference of 102
> > last=1 ==> a time difference of 155
> > last=1 ==> a time difference of 105
> > Interesting that whenever this happens its on the first iteration.
> >
> > 2. Invalid consecutive ids.
> > self assert: (uuid1 at: 10) + 1 equals: (uuid2 at: 10).
> > last=127 ==> TestFailure: Got 256 instead of 0.
> > last=828 ==> TestFailure: Got 256 instead of 0.
> > last=128 ==> TestFailure: Got 256 instead of 0.
> > last=316 ==> TestFailure: Got 256 instead of 0.
> > Maybe a problem with rollover?
> >
> > So instrumenting a bit:
> > testTwoSameGenerator: n
> > | uuid1 uuid2 consecutiveOk time1 time2 timeOk |
> > ....
> > "same generator, consequetive counters"
> > consecutiveOk := ((uuid1 at: 10) + 1) = (uuid2 at: 10).
> > "same generators, similar clock, within 100 milliseconds"
> > time1 := self timeFromUUID: uuid1.
> > time2 := self timeFromUUID: uuid2.
> > timeOk := (time2 - time1) abs < 100.
> > ( timeOk and: [ consecutiveOk ]) ifFalse: [
> > Transcript cr;
> > show: 'fail n=', (n printPaddedWith: $0 to: 3) ; tab;
> > show: ' time ', ((time2 - time1) printString) , '<100'; tab;
> > show: ' uuid ', (((uuid1 at: 10) + 1) printString, '=',
> (uuid2 at: 10) printString).
> > ].
> > self assert: consecutiveOk.
> > self assert: timeOk.
> >
> > From playground running...
> > 1 to: 1000 do: [:n|
> > NeoUUIDGeneratorTests new setUp testTwoSameGenerator: n].
> > Transcript crShow: 'x'.
> >
> > Note the 'x' was not output due to one of the consecutiveOk or timeOk
> asserts triggered each run.
> > fail n=001 time 104<100 uuid 160=160
> > fail n=269 time 2<100 uuid 256=0
> > fail n=001 time 152<100 uuid 166=166
> > fail n=117 time 3<100 uuid 256=0
> > fail n=001 time 123<100 uuid 128=128
> > fail n=278 time 3<100 uuid 256=0
> > fail n=001 time 145<100 uuid 230=230
> > fail n=673 time 1340<100 uuid 141=141
> > fail n=707 time 3<100 uuid 256=0
> > fail n=001 time 132<100 uuid 73=73
> > fail n=001 time 117<100 uuid 206=206
> > fail n=063 time 2<100 uuid 256=0
> > fail n=345 time 3<100 uuid 256=0
> >
> > Now a strange thing is that after commenting out those two asserts for
> consecutiveOk and timeOk, the fails at n=001 stop happening.
> >
> > fail n=001 time 141<100 uuid 232=232
> > x
> > x
> > fail n=201 time 3<100 uuid 256=0
> > fail n=268 time 3<100 uuid 256=0
> > fail n=359 time 3<100 uuid 256=0
> > fail n=408 time 2<100 uuid 256=0
> > fail n=559 time 3<100 uuid 256=0
> > x
> > fail n=139 time 3<100 uuid 256=0
> > fail n=854 time 7<100 uuid 256=0
> > x
> > fail n=389 time 3<100 uuid 256=0
> > fail n=669 time 3<100 uuid 256=0
> > fail n=876 time 3<100 uuid 256=0
> > fail n=916 time 3<100 uuid 256=0
> > fail n=953 time 2<100 uuid 256=0
> > fail n=954 time 3<100 uuid 256=0
> > x
> > fail n=148 time 3<100 uuid 256=0
> > fail n=741 time 3<100 uuid 256=0
> > x
> > fail n=116 time 2<100 uuid 256=0
> > fail n=480 time 3<100 uuid 256=0
> > x
> >
> > After treating the rollover like this...
> > consecutiveOk := ((uuid1 at: 10) + 1) \\ 256 = (uuid2 at: 10).
> > running the last playground script gives...
> >
> > (Note the n=001 fail reoccurs after waiting a while between running the
> playground script again.)
> > fail n=001 time 123<100 uuid 110=110
> > x
> > fail n=345 time 1287<100 uuid 24=24
> > fail n=404 time 1313<100 uuid 125=125
> > x
> > x
> > x
> > x
> > x
> > fail n=449 time 1290<100 uuid 24=24
> > x
> > x
> > x
> > x
> > x
> >
> >
> > Thats looking better, so upping to 10000 iterations...
> > fail n=0001 time 151<100 uuid 160=160
> > fail n=2977 time 1437<100 uuid 221=221
> > fail n=5498 time 1454<100 uuid 224=224
> > fail n=9007 time 1351<100 uuid 239=239
> > x
> > fail n=3389 time 1381<100 uuid 223=223
> > fail n=7768 time 1365<100 uuid 82=82
> > fail n=9773 time 1395<100 uuid 164=164
> > x
> > fail n=3325 time 1448<100 uuid 67=67
> > fail n=9930 time 1456<100 uuid 103=103
> > x
> > fail n=0060 time 2914<100 uuid 159=159
> > fail n=1829 time 1438<100 uuid 32=32
> > fail n=7918 time 1436<100 uuid 182=182
> > x
> >
> > So the rollover looks cured.
> >
> > Now adding some more instrumentation to view GC Time and Time To Run
> > and (see attached ST file)
> >
> > 0:00:00:00 TTR 0:00:00:00.001 TTR 0:00:00:00 TTR 0:00:00:00
> TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR
> 0:00:00:00 TTR 0:00:00:00
> > x
> > fail n=0001 time 115<100 uuid 157=157 GCTime 0 TTR 0:00:00:00
> > fail n=0001 time 2<100 uuid 255=0 GCTime 0 TTR 0:00:00:00
> > x
> > fail n=0001 time 111<100 uuid 104=104 GCTime 0 TTR 0
> > x
> > fail n=0001 time 120<100 uuid 204=204 GCTime 0 TTR 0
> > fail n=0001 time 1182<100 uuid 103=103 GCTime 1 TTR 1
> > x
> > x
> > x
> > x
> > x
> > fail n=0001 time 3<100 uuid 255=0 GCTime 0 TTR 0
> > x
> > x
> > fail n=0001 time 1251<100 uuid 253=253 GCTime 2 TTR 1
> > x
> >
> >
> > Now I wonder at the class comment saying...
> > "the first 8 bytes are the *millisecond* clock value"
> > but #clockOn: is using *microsecond* clock.
> > Perhaps "self assert: (time2 - time1) abs < 100"
> > is meant to be 100ms not 100us ??
> >
> > cheers -ben
> >
> > [1] https://pharo.fogbugz.com/f/cases/19438
> > [2]
> > https://ci.inria.fr/pharo/job/Pharo-6.0-Issue-Validator/19471//artifac
> > t/validationReport.html
> > <NeoUUIDGeneratorTests-testTwoSameGenerator.st>
>
>
>
>
Dec. 11, 2016
Re: [Pharo-dev] NeoUUIDGenerator>>testTwoSameGenerator - intermittent CI failure
by Sven Van Caekenberghe
> On 11 Dec 2016, at 12:49, Henrik Nergaard <henrik.nergaard(a)uia.no> wrote:
>
>> The timing problem might indeed be resolution dependent: 100us is probably to short sometimes.
> Time microsecondClockValue gives the time in microseconds, but it does not guarantee microsecond resolution, on windows the resolution is still in milliseconds.
>
> ----------
> | col |
>
> col := Array new: 30000 streamContents: [ :stream |
> 1 to: 30000 do: [ :x | stream nextPut: Time microsecondClockValue ]
> ].
>
> col asSet "a Set(3658909536504622 3658909536503622 3658909536502622)"'
> ---------
Cool test, very sad result ;-)
> Best regards,
> Henrik
>
> -----Original Message-----
> From: Pharo-dev [mailto:pharo-dev-bounces@lists.pharo.org] On Behalf Of Sven Van Caekenberghe
> Sent: Sunday, December 11, 2016 11:56 AM
> To: Pharo Development List <pharo-dev(a)lists.pharo.org>
> Subject: Re: [Pharo-dev] NeoUUIDGenerator>>testTwoSameGenerator - intermittent CI failure
>
> Hi Ben,
>
> Thanks for looking into this, it was bothering me for quite some time ;-)
>
> https://pharo.fogbugz.com/f/cases/19453/NeoUUIDGenerator-testTwoSameGenerat…
>
> Yes, I think the counter roll-over is the problem, stupid of me to to have seen this.
>
> The timing problem might indeed be resolution dependent: 100us is probably to short sometimes.
>
> I will provide a slice with fixes.
>
> Thanks again !
>
> Regards,
>
> Sven
>
>> On 11 Dec 2016, at 09:07, Ben Coman <btc(a)openinworld.com> wrote:
>>
>> For Case [1] I got an unrelated CI failure [2] for
>> NeoUUIDGeneratorTests>>#testTwoSameGenerator
>>
>> Checking this locally by running this a dozen times...
>> 1 to: 1000 do: [:n| last:=n. NeoUUIDGeneratorTests new setUp
>> testTwoSameGenerator ]
>>
>> Two distinct failures are apparent...
>>
>> 1. Takes longer than expected.
>> self assert: (time2 - time1) abs < 100
>> last=1 ==> a time difference of 109
>> last=1 ==> a time difference of 102
>> last=1 ==> a time difference of 155
>> last=1 ==> a time difference of 105
>> Interesting that whenever this happens its on the first iteration.
>>
>> 2. Invalid consecutive ids.
>> self assert: (uuid1 at: 10) + 1 equals: (uuid2 at: 10).
>> last=127 ==> TestFailure: Got 256 instead of 0.
>> last=828 ==> TestFailure: Got 256 instead of 0.
>> last=128 ==> TestFailure: Got 256 instead of 0.
>> last=316 ==> TestFailure: Got 256 instead of 0.
>> Maybe a problem with rollover?
>>
>> So instrumenting a bit:
>> testTwoSameGenerator: n
>> | uuid1 uuid2 consecutiveOk time1 time2 timeOk |
>> ....
>> "same generator, consequetive counters"
>> consecutiveOk := ((uuid1 at: 10) + 1) = (uuid2 at: 10).
>> "same generators, similar clock, within 100 milliseconds"
>> time1 := self timeFromUUID: uuid1.
>> time2 := self timeFromUUID: uuid2.
>> timeOk := (time2 - time1) abs < 100.
>> ( timeOk and: [ consecutiveOk ]) ifFalse: [
>> Transcript cr;
>> show: 'fail n=', (n printPaddedWith: $0 to: 3) ; tab;
>> show: ' time ', ((time2 - time1) printString) , '<100'; tab;
>> show: ' uuid ', (((uuid1 at: 10) + 1) printString, '=', (uuid2 at: 10) printString).
>> ].
>> self assert: consecutiveOk.
>> self assert: timeOk.
>>
>> From playground running...
>> 1 to: 1000 do: [:n|
>> NeoUUIDGeneratorTests new setUp testTwoSameGenerator: n].
>> Transcript crShow: 'x'.
>>
>> Note the 'x' was not output due to one of the consecutiveOk or timeOk asserts triggered each run.
>> fail n=001 time 104<100 uuid 160=160
>> fail n=269 time 2<100 uuid 256=0
>> fail n=001 time 152<100 uuid 166=166
>> fail n=117 time 3<100 uuid 256=0
>> fail n=001 time 123<100 uuid 128=128
>> fail n=278 time 3<100 uuid 256=0
>> fail n=001 time 145<100 uuid 230=230
>> fail n=673 time 1340<100 uuid 141=141
>> fail n=707 time 3<100 uuid 256=0
>> fail n=001 time 132<100 uuid 73=73
>> fail n=001 time 117<100 uuid 206=206
>> fail n=063 time 2<100 uuid 256=0
>> fail n=345 time 3<100 uuid 256=0
>>
>> Now a strange thing is that after commenting out those two asserts for consecutiveOk and timeOk, the fails at n=001 stop happening.
>>
>> fail n=001 time 141<100 uuid 232=232
>> x
>> x
>> fail n=201 time 3<100 uuid 256=0
>> fail n=268 time 3<100 uuid 256=0
>> fail n=359 time 3<100 uuid 256=0
>> fail n=408 time 2<100 uuid 256=0
>> fail n=559 time 3<100 uuid 256=0
>> x
>> fail n=139 time 3<100 uuid 256=0
>> fail n=854 time 7<100 uuid 256=0
>> x
>> fail n=389 time 3<100 uuid 256=0
>> fail n=669 time 3<100 uuid 256=0
>> fail n=876 time 3<100 uuid 256=0
>> fail n=916 time 3<100 uuid 256=0
>> fail n=953 time 2<100 uuid 256=0
>> fail n=954 time 3<100 uuid 256=0
>> x
>> fail n=148 time 3<100 uuid 256=0
>> fail n=741 time 3<100 uuid 256=0
>> x
>> fail n=116 time 2<100 uuid 256=0
>> fail n=480 time 3<100 uuid 256=0
>> x
>>
>> After treating the rollover like this...
>> consecutiveOk := ((uuid1 at: 10) + 1) \\ 256 = (uuid2 at: 10).
>> running the last playground script gives...
>>
>> (Note the n=001 fail reoccurs after waiting a while between running the playground script again.)
>> fail n=001 time 123<100 uuid 110=110
>> x
>> fail n=345 time 1287<100 uuid 24=24
>> fail n=404 time 1313<100 uuid 125=125
>> x
>> x
>> x
>> x
>> x
>> fail n=449 time 1290<100 uuid 24=24
>> x
>> x
>> x
>> x
>> x
>>
>>
>> Thats looking better, so upping to 10000 iterations...
>> fail n=0001 time 151<100 uuid 160=160
>> fail n=2977 time 1437<100 uuid 221=221
>> fail n=5498 time 1454<100 uuid 224=224
>> fail n=9007 time 1351<100 uuid 239=239
>> x
>> fail n=3389 time 1381<100 uuid 223=223
>> fail n=7768 time 1365<100 uuid 82=82
>> fail n=9773 time 1395<100 uuid 164=164
>> x
>> fail n=3325 time 1448<100 uuid 67=67
>> fail n=9930 time 1456<100 uuid 103=103
>> x
>> fail n=0060 time 2914<100 uuid 159=159
>> fail n=1829 time 1438<100 uuid 32=32
>> fail n=7918 time 1436<100 uuid 182=182
>> x
>>
>> So the rollover looks cured.
>>
>> Now adding some more instrumentation to view GC Time and Time To Run
>> and (see attached ST file)
>>
>> 0:00:00:00 TTR 0:00:00:00.001 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00 TTR 0:00:00:00
>> x
>> fail n=0001 time 115<100 uuid 157=157 GCTime 0 TTR 0:00:00:00
>> fail n=0001 time 2<100 uuid 255=0 GCTime 0 TTR 0:00:00:00
>> x
>> fail n=0001 time 111<100 uuid 104=104 GCTime 0 TTR 0
>> x
>> fail n=0001 time 120<100 uuid 204=204 GCTime 0 TTR 0
>> fail n=0001 time 1182<100 uuid 103=103 GCTime 1 TTR 1
>> x
>> x
>> x
>> x
>> x
>> fail n=0001 time 3<100 uuid 255=0 GCTime 0 TTR 0
>> x
>> x
>> fail n=0001 time 1251<100 uuid 253=253 GCTime 2 TTR 1
>> x
>>
>>
>> Now I wonder at the class comment saying...
>> "the first 8 bytes are the *millisecond* clock value"
>> but #clockOn: is using *microsecond* clock.
>> Perhaps "self assert: (time2 - time1) abs < 100"
>> is meant to be 100ms not 100us ??
>>
>> cheers -ben
>>
>> [1] https://pharo.fogbugz.com/f/cases/19438
>> [2]
>> https://ci.inria.fr/pharo/job/Pharo-6.0-Issue-Validator/19471//artifac
>> t/validationReport.html
>> <NeoUUIDGeneratorTests-testTwoSameGenerator.st>
>
>
>
Dec. 11, 2016