[squeak-dev] How to profile a server image?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
47 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: How to profile a server image?

Igor Stasenko
2009/3/4 Andreas Raab <[hidden email]>:

> Igor Stasenko wrote:
>>
>> Guys, can i ask you to put these recommendations on wiki page, so this
>> VERY USEFUL guide will not be buried in mailing list and can serve as
>> a basic guide for profiling in Squeak?
>
> Where would you put it? I have never found my way through the Wiki. If it's
> helpful for others I'd be happy to put it up, just tell me where you'd like
> it to go.
>

There is a wiki page, already dedicated to it
http://wiki.squeak.org/squeak/1799

Or , maybe its worth create a new page 'Profiling in Squeak' .. or
give it more appropriate name

> Cheers,
>  - Andreas
>
>



--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: How to profile a server image?

Juan Vuletich-4
In reply to this post by Eliot Miranda-2
Hi Eliot,

Eliot Miranda wrote:

>
> ...
>
> I think I see but I wouldn't put it like that.  Yes, new processes get
> resumed in the context of other proesses, but no, the sender is not in
> another process.  The bottom context of a process has no sender.  So
> why bother at all trying to track down in which process a process was
> created and leave that to the user when interpreting the profile?
>
>     I made it work, by adding an ivar to Process to hold the
>     firstContext (the one that is sent to #forContext:priority:).
>     Then, when building the tally tree, for each context, I check if
>     it is the firstContext of some process. The problem with this
>     approach is that it adds too much overhead to the tally.
>
>
> IMO just throw this away.  You don't absolutely need to know on behalf
> of which process a process is running.
>
>     I'd really appreciate a better way to do this. I'm sure everybody
>     will like the multi-process tally that would result!
>
>
> I believe the VW multi-process profiler doesn't bother identifying the
> parent process.  But if it does it can do so by e.g. adding an inst
> var to process that refers to the parent process, rather than the
> context in which the process was created.  But both recording the
> context or the parent process are bad ideas for garbage collection.
>
> I would simply use the process name facility (Process>>name[:] as
> displayed by the process browser) to label the various tallies you
> collect.  If a user can't work out which process is which by just
> looking at the the profile ten they can change their code to use
> Process>>name: to add names to various processes and then be able to
> wrk it out.
>
> just my 2¢
>
> best
> E.

I'm not interested at all on identifying the parent process. To make my
aim clearer, let's see an example:

    [1000 timesRepeat: [3.14159 printString. Processor yield]] fork.
    [1000 timesRepeat: [30 factorial. Processor yield]] fork.
    [1000 timesRepeat: [30 factorial. Processor yield]] fork.
    MessageTally spyOn: [ (Delay forMilliseconds: 100) wait]

Without Andreas fixes, it gives a completely useless answer, as if all
the time was spent in the Delay.

With Andreas' fix, it gives:

**Tree**
55.0% {55ms} SmallInteger(Integer)>>factorial
  |50.0% {50ms} SmallInteger(Integer)>>factorial
  |  47.0% {47ms} SmallInteger(Integer)>>factorial
  |    42.0% {42ms} SmallInteger(Integer)>>factorial
  |      39.0% {39ms} SmallInteger(Integer)>>factorial
  |        33.0% {33ms} SmallInteger(Integer)>>factorial
  |          30.0% {30ms} SmallInteger(Integer)>>factorial
  |            23.0% {23ms} SmallInteger(Integer)>>factorial
  |              22.0% {22ms} SmallInteger(Integer)>>factorial
  |                18.0% {18ms} SmallInteger(Integer)>>factorial
  |                  18.0% {18ms} SmallInteger(Integer)>>factorial
  |                    16.0% {16ms} SmallInteger(Integer)>>factorial
  |                      14.0% {14ms} SmallInteger(Integer)>>factorial
  |                        11.0% {11ms} SmallInteger(Integer)>>factorial
23.0% {23ms} Float(Object)>>printString
  23.0% {23ms} Float(Object)>>printStringLimitedTo:
    20.0% {20ms} Float(Number)>>printOn:
      18.0% {18ms} Float>>printOn:base:
        18.0% {18ms} Float>>absPrintOn:base:

It could separate the first forked process, but only because it runs
different code (#printString). Both processes running #factorial are
shown together. It is true that a context with no sender (the bottom of
a stack) is a root at the tree. But we can not know to which process
they belong. Therefore I can not decorate each tree with a process name!

What I can get with my code is:

**Tree**
-----------------------------------
unknown process
-----------------------------------
29.2% {31ms} BlockContext>>newProcess
  |29.2% {31ms} ProcessorScheduler class>>startUp
  |  29.2% {31ms} ProcessorScheduler class>>idleProcess
-----------------------------------
(40) process named:  1992
-----------------------------------
28.3% {30ms} MessageTally class>>DoIt
  |28.3% {30ms} SmallInteger(Integer)>>timesRepeat:
  |  26.4% {28ms} MessageTally class>>DoIt
  |    26.4% {28ms} Float(Object)>>printString
  |      25.5% {27ms} Float(Object)>>printStringLimitedTo:
  |        25.5% {27ms} String class(SequenceableCollection
class)>>streamContents:limitedTo:
  |          22.6% {24ms} Float(Object)>>printStringLimitedTo:
  |            22.6% {24ms} Float(Number)>>printOn:
  |              21.7% {23ms} Float>>printOn:base:
  |                21.7% {23ms} Float>>absPrintOn:base:
-----------------------------------
(40) process named:  2910
-----------------------------------
17.9% {19ms} MessageTally class>>DoIt
  |17.9% {19ms} SmallInteger(Integer)>>timesRepeat:
  |  17.0% {18ms} MessageTally class>>DoIt
  |    17.0% {18ms} SmallInteger(Integer)>>factorial
  |      15.1% {16ms} SmallInteger(Integer)>>factorial
  |        12.3% {13ms} SmallInteger(Integer)>>factorial
-----------------------------------
(40) process named:   893
-----------------------------------
15.1% {16ms} MessageTally class>>DoIt
  15.1% {16ms} SmallInteger(Integer)>>timesRepeat:
    15.1% {16ms} MessageTally class>>DoIt
      15.1% {16ms} SmallInteger(Integer)>>factorial
        14.2% {15ms} SmallInteger(Integer)>>factorial
          14.2% {15ms} SmallInteger(Integer)>>factorial
            13.2% {14ms} SmallInteger(Integer)>>factorial
              13.2% {14ms} SmallInteger(Integer)>>factorial

I can get the tally for each process. Many times this will be much
easier to optimize the application, especially if each process can have
a meaningful name, and a well known purpose.

If you say that the process holding a reference to the first context it
ran is bad for GC, I take your word. But I'd really like to solve this
problem.

Thanks,
Juan Vuletich

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: How to profile a server image?

Juan Vuletich-4
In reply to this post by Andreas.Raab
Hi Andreas,

Andreas Raab wrote:

> Juan Vuletich wrote:
>> What you say sounds similar to what Andreas suggests to make
>> MessageTally spy over all processes. The issue I point out is that
>> when MessageTally
>> builds the tree, the sender of a context might be in another process.
>> This happens when a context forks a new process, it is still its
>> sender. So when building the tally tree, I need to query each context
>> for the process running it, and when it is different from the
>> parent's one, I'll start a new tally tree.
>
> I'm not sure how useful this is. When it comes to measuring where the
> time goes, the cumulative tree of multiple processes shows you if you
> have deficiencies in the core framework handling. This is extremely
> useful. And it breaks down quite nicely into separate pieces where
> actual different work is involved. I don't think you would get much
> more useful information if you were to break things apart. And I can
> say for sure that for the purposes of our server profiling it would be
> pretty much useless - under load we run literally hundreds of processes.
>
> Cheers,
>   - Andreas
>
>
>

I understand that for a server having an variable (and big) number of
processes it is not useful. But for our case, an application with a
small and fixed set of processes, the first question we want to answer
is "which is the process using all the cpu?". Please see the message I
just sent on this thread to see an example of what I want.

Thanks,
Juan Vuletich

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: How to profile a server image?

Andreas.Raab
In reply to this post by Juan Vuletich-4
Juan Vuletich wrote:

> I'm not interested at all on identifying the parent process. To make my
> aim clearer, let's see an example:
>
>    [1000 timesRepeat: [3.14159 printString. Processor yield]] fork.
>    [1000 timesRepeat: [30 factorial. Processor yield]] fork.
>    [1000 timesRepeat: [30 factorial. Processor yield]] fork.
>    MessageTally spyOn: [ (Delay forMilliseconds: 100) wait]
>
> Without Andreas fixes, it gives a completely useless answer, as if all
> the time was spent in the Delay.

Ah, very good! I've been looking for an example that illustrates just
that. This is extremely helpful. For our purposes (lots of processes,
you want to profile overall server behavior) the cumulative tree is the
only useful response. There would be no point whatsoever even trying to
separate hundreds of processes (it is statistical profiling after all).

However, I can see that in some situations your view might be useful for
some people. I would guess that the easiest way to distinguish processes
would be look at the identity of the context that is at the root of the
call tree. If you send me the code I'll see if I can come up with a
clever way to have our cake and eat it, too.

Cheers,
   - Andreas


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Community blog? (was: Re: How to profile a server image?)

Andreas.Raab
In reply to this post by Igor Stasenko
Igor Stasenko wrote:
> There is a wiki page, already dedicated to it
> http://wiki.squeak.org/squeak/1799
>
> Or , maybe its worth create a new page 'Profiling in Squeak' .. or
> give it more appropriate name

Now up at http://wiki.squeak.org/squeak/6122

Which reminds me: I had forgotten how much I hate the Swiki. It is ugly,
horribly conflated, and effectively unusable. Should we replace the damn
thing with a community blog instead? I think this might be a better way
of dealing with the information overload - you get dated, tagged entry
and if we keep this open for pretty much every member of the community
(using the "standard" username/password from the Swiki) we could use it
much the same.

I'd be more than willing to write up my post as a blog article instead.
I just don't have a blog and even if I had I doubt many people would use
it. A community blog could be a nice, lively place to post your thoughts
in a bit more organized manner and would make an attractive target for
people who just want to know what's going on in the world of Squeak.

Cheers,
   - Andreas


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Community blog? (was: Re: How to profile a server image?)

Igor Stasenko
2009/3/4 Andreas Raab <[hidden email]>:

> Igor Stasenko wrote:
>>
>> There is a wiki page, already dedicated to it
>> http://wiki.squeak.org/squeak/1799
>>
>> Or , maybe its worth create a new page 'Profiling in Squeak' .. or
>> give it more appropriate name
>
> Now up at http://wiki.squeak.org/squeak/6122
>
> Which reminds me: I had forgotten how much I hate the Swiki. It is ugly,
> horribly conflated, and effectively unusable. Should we replace the damn
> thing with a community blog instead? I think this might be a better way of
> dealing with the information overload - you get dated, tagged entry and if
> we keep this open for pretty much every member of the community (using the
> "standard" username/password from the Swiki) we could use it much the same.
>
> I'd be more than willing to write up my post as a blog article instead. I
> just don't have a blog and even if I had I doubt many people would use it. A
> community blog could be a nice, lively place to post your thoughts in a bit
> more organized manner and would make an attractive target for people who
> just want to know what's going on in the world of Squeak.
>

we had a http://people.squeak.org/
which has a kind of blogging facilities, but now it looks like dead.
The page is different.

P.S. +1 for having a community blog.

> Cheers,
>  - Andreas
>
>
>



--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Community blog? (was: Re: How to profile a server image?)

Steve Wart
In reply to this post by Andreas.Raab
+1

Steve

On 3 Mar 2009, at 18:25, Andreas Raab <[hidden email]> wrote:

> Igor Stasenko wrote:
>> There is a wiki page, already dedicated to it
>> http://wiki.squeak.org/squeak/1799
>> Or , maybe its worth create a new page 'Profiling in Squeak' .. or
>> give it more appropriate name
>
> Now up at http://wiki.squeak.org/squeak/6122
>
> Which reminds me: I had forgotten how much I hate the Swiki. It is  
> ugly, horribly conflated, and effectively unusable. Should we  
> replace the damn thing with a community blog instead? I think this  
> might be a better way of dealing with the information overload - you  
> get dated, tagged entry and if we keep this open for pretty much  
> every member of the community (using the "standard" username/
> password from the Swiki) we could use it much the same.
>
> I'd be more than willing to write up my post as a blog article  
> instead. I just don't have a blog and even if I had I doubt many  
> people would use it. A community blog could be a nice, lively place  
> to post your thoughts in a bit more organized manner and would make  
> an attractive target for people who just want to know what's going  
> on in the world of Squeak.
>
> Cheers,
>  - Andreas
>
>

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: How to profile a server image?

Andreas.Raab
In reply to this post by Juan Vuletich-4
Juan Vuletich wrote:
> I understand that for a server having an variable (and big) number of
> processes it is not useful. But for our case, an application with a
> small and fixed set of processes, the first question we want to answer
> is "which is the process using all the cpu?". Please see the message I
> just sent on this thread to see an example of what I want.

Okay, I cracked ;-) Attached you'll find patches for a message tally
version which does per-process reporting if so desired. I've moved this
out of the arguments and into class variables so you get/set either
priority or preference via, e.g.:

   MessageTally spyPriority: <new priority>
   MessageTally showProcesses: <true/false>

The defaults are such that the priority is TimerPriority-1 and
showProcesses is on. With it, your example gives the result shown below.

Let me know if this works for you (or anyone else). Comments welcome.

Cheers,
   - Andreas

  - 101 tallies, 101 msec.

**Tree**
--------------------------------
Process: (40)  3420: [] in UndefinedObject>>DoIt {[3.14159 printString.
  Processor yield]}
--------------------------------
23.8% {24ms} Float(Number)>>printStringBase:
   21.8% {22ms} Float>>printOn:base:
     20.8% {21ms} Float>>absPrintOn:base:
       6.9% {7ms} False>>|
       5.9% {6ms} primitives
       3.0% {3ms} WriteStream>>nextPut:
--------------------------------
Process: (40)  1426: [] in UndefinedObject>>DoIt {[30 factorial.
Processor yield]}
--------------------------------
29.7% {30ms} SmallInteger(Integer)>>factorial
   26.7% {27ms} SmallInteger(Integer)>>factorial
     |24.8% {25ms} SmallInteger(Integer)>>factorial
     |  22.8% {23ms} SmallInteger(Integer)>>factorial
     |    21.8% {22ms} SmallInteger(Integer)>>factorial
     |      20.8% {21ms} SmallInteger(Integer)>>factorial
     |        16.8% {17ms} SmallInteger(Integer)>>factorial
     |          |14.9% {15ms} SmallInteger(Integer)>>factorial
     |          |  13.9% {14ms} SmallInteger(Integer)>>factorial
     |          |    10.9% {11ms} SmallInteger(Integer)>>factorial
     |          |      |8.9% {9ms} SmallInteger(Integer)>>factorial
     |          |      |  7.9% {8ms} SmallInteger(Integer)>>factorial
     |          |      |    6.9% {7ms} SmallInteger(Integer)>>factorial
     |          |      |      5.0% {5ms} SmallInteger(Integer)>>factorial
     |          |      |        5.0% {5ms} SmallInteger(Integer)>>factorial
     |          |      |          3.0% {3ms}
SmallInteger(Integer)>>factorial
     |          |      |            3.0% {3ms}
SmallInteger(Integer)>>factorial
     |          |    3.0% {3ms} SmallInteger>>*
     |        4.0% {4ms} SmallInteger>>*
   3.0% {3ms} SmallInteger>>*
--------------------------------
Process: (40)  3777: [] in UndefinedObject>>DoIt {[30 factorial.
Processor yield]}
--------------------------------
40.6% {41ms} SmallInteger(Integer)>>factorial
   38.6% {39ms} SmallInteger(Integer)>>factorial
     37.6% {38ms} SmallInteger(Integer)>>factorial
       35.6% {36ms} SmallInteger(Integer)>>factorial
         30.7% {31ms} SmallInteger(Integer)>>factorial
           |26.7% {27ms} SmallInteger(Integer)>>factorial
           |  |23.8% {24ms} SmallInteger(Integer)>>factorial
           |  |  |22.8% {23ms} SmallInteger(Integer)>>factorial
           |  |  |  21.8% {22ms} SmallInteger(Integer)>>factorial
           |  |  |    21.8% {22ms} SmallInteger(Integer)>>factorial
           |  |  |      19.8% {20ms} SmallInteger(Integer)>>factorial
           |  |  |        17.8% {18ms} SmallInteger(Integer)>>factorial
           |  |  |          14.9% {15ms} SmallInteger(Integer)>>factorial
           |  |  |            |9.9% {10ms} SmallInteger(Integer)>>factorial
           |  |  |            |  |7.9% {8ms}
SmallInteger(Integer)>>factorial
           |  |  |            |  |  5.9% {6ms}
SmallInteger(Integer)>>factorial
           |  |  |            |  |    3.0% {3ms} SmallInteger>>*
           |  |  |            |  |    3.0% {3ms}
SmallInteger(Integer)>>factorial
           |  |  |            |5.0% {5ms} SmallInteger>>*
           |  |  |            |  3.0% {3ms} primitives
           |  |  |          3.0% {3ms} SmallInteger>>*
           |  |3.0% {3ms} SmallInteger>>*
           |4.0% {4ms} SmallInteger>>*
         5.0% {5ms} SmallInteger>>*
           3.0% {3ms} primitives

**Leaves**
51.5% {52ms} SmallInteger>>*
7.9% {8ms} SmallInteger(Number)>>negative
6.9% {7ms} False>>|
5.9% {6ms} Float>>absPrintOn:base:
5.0% {5ms} SmallInteger(Integer)>>*
5.0% {5ms} False(ProtoObject)>>~~
4.0% {4ms} SmallInteger(Integer)>>factorial

**Memory**
        old +0 bytes
        young -70,492 bytes
        used -70,492 bytes
        free +70,492 bytes

**GCs**
        full 0 totalling 0ms (0.0% uptime)
        incr 17 totalling 13ms (13.0% uptime), avg 1.0ms
        tenures 0
        root table 0 overflows




MessageTallyEnh-ar.2.cs (8K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: [squeak-dev] Community blog? (was: Re: How to profile a server image?)

Larry Trutter
In reply to this post by Andreas.Raab
+1

Larry Trutter

> Date: Tue, 3 Mar 2009 18:25:35 -0800
> From: [hidden email]
> To: [hidden email]
> Subject: [squeak-dev] Community blog? (was: Re: How to profile a server image?)
>
> Igor Stasenko wrote:
> > There is a wiki page, already dedicated to it
> > http://wiki.squeak.org/squeak/1799
> >
> > Or , maybe its worth create a new page 'Profiling in Squeak' .. or
> > give it more appropriate name
>
> Now up at http://wiki.squeak.org/squeak/6122
>
> Which reminds me: I had forgotten how much I hate the Swiki. It is ugly,
> horribly conflated, and effectively unusable. Should we replace the damn
> thing with a community blog instead? I think this might be a better way
> of dealing with the information overload - you get dated, tagged entry
> and if we keep this open for pretty much every member of the community
> (using the "standard" username/password from the Swiki) we could use it
> much the same.
>
> I'd be more than willing to write up my post as a blog article instead.
> I just don't have a blog and even if I had I doubt many people would use
> it. A community blog could be a nice, lively place to post your thoughts
> in a bit more organized manner and would make an attractive target for
> people who just want to know what's going on in the world of Squeak.
>
> Cheers,
> - Andreas
>
>


Windows Live™ Contacts: Organize your contact list. Check it out.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: How to profile a server image?

johnmci
In reply to this post by Juan Vuletich-4
A long time ago I suggested that you could track CPU usage, or  
dispatch clock time in
Interpreter>>transferTo: aProc  since that still is the only place a  
transfer switch occurs between processes.
You could collect more things too, like network traffic etc.
I've always thought the benefit is that you don't have some ugly high  
priority watcher task thundering about
creating garbage and leaving foot prints in the cake...


http://lists.squeakfoundation.org/pipermail/squeak-dev/2001-March/015945.html


On 3-Mar-09, at 5:31 PM, Juan Vuletich wrote:

> Hi Andreas,
>
> Andreas Raab wrote:
>> Juan Vuletich wrote:
>>> What you say sounds similar to what Andreas suggests to make  
>>> MessageTally spy over all processes. The issue I point out is that  
>>> when MessageTally
>>> builds the tree, the sender of a context might be in another  
>>> process. This happens when a context forks a new process, it is  
>>> still its sender. So when building the tally tree, I need to query  
>>> each context for the process running it, and when it is different  
>>> from the parent's one, I'll start a new tally tree.
>>
>> I'm not sure how useful this is. When it comes to measuring where  
>> the time goes, the cumulative tree of multiple processes shows you  
>> if you have deficiencies in the core framework handling. This is  
>> extremely useful. And it breaks down quite nicely into separate  
>> pieces where actual different work is involved. I don't think you  
>> would get much more useful information if you were to break things  
>> apart. And I can say for sure that for the purposes of our server  
>> profiling it would be pretty much useless - under load we run  
>> literally hundreds of processes.
>>
>> Cheers,
>>  - Andreas
>>
>>
>>
>
> I understand that for a server having an variable (and big) number  
> of processes it is not useful. But for our case, an application with  
> a small and fixed set of processes, the first question we want to  
> answer is "which is the process using all the cpu?". Please see the  
> message I just sent on this thread to see an example of what I want.
>
> Thanks,
> Juan Vuletich
>

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Community blog?

Giuseppe
In reply to this post by Andreas.Raab
A blog and a wiki is not for the same purpposes IMHO.

Maybe, could be interesting, migrate the actual wiki, to some new over
Seaside-Pier / Aida-Scribo.

Cheers.

Andreas Raab escribió:

> Igor Stasenko wrote:
>> There is a wiki page, already dedicated to it
>> http://wiki.squeak.org/squeak/1799
>>
>> Or , maybe its worth create a new page 'Profiling in Squeak' .. or
>> give it more appropriate name
>
> Now up at http://wiki.squeak.org/squeak/6122
>
> Which reminds me: I had forgotten how much I hate the Swiki. It is
> ugly, horribly conflated, and effectively unusable. Should we replace
> the damn thing with a community blog instead? I think this might be a
> better way of dealing with the information overload - you get dated,
> tagged entry and if we keep this open for pretty much every member of
> the community (using the "standard" username/password from the Swiki)
> we could use it much the same.
>
> I'd be more than willing to write up my post as a blog article
> instead. I just don't have a blog and even if I had I doubt many
> people would use it. A community blog could be a nice, lively place to
> post your thoughts in a bit more organized manner and would make an
> attractive target for people who just want to know what's going on in
> the world of Squeak.
>
> Cheers,
>   - Andreas
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Community blog? (was: Re: How to profile a serverimage?)

Frank Shearar
In reply to this post by Andreas.Raab
"Andreas Raab" <[hidden email]> wrote:

> Igor Stasenko wrote:
> > There is a wiki page, already dedicated to it
> > http://wiki.squeak.org/squeak/1799
> >
> > Or , maybe its worth create a new page 'Profiling in Squeak' .. or
> > give it more appropriate name
>
> Now up at http://wiki.squeak.org/squeak/6122
>
> Which reminds me: I had forgotten how much I hate the Swiki. It is ugly,
> horribly conflated, and effectively unusable. Should we replace the damn
> thing with a community blog instead? I think this might be a better way
> of dealing with the information overload - you get dated, tagged entry
> and if we keep this open for pretty much every member of the community
> (using the "standard" username/password from the Swiki) we could use it
> much the same.
>
> I'd be more than willing to write up my post as a blog article instead.
> I just don't have a blog and even if I had I doubt many people would use
> it. A community blog could be a nice, lively place to post your thoughts
> in a bit more organized manner and would make an attractive target for
> people who just want to know what's going on in the world of Squeak.

Well, I'd follow your blog, for one. But http://planet.squeak.org/ is pretty
darn cool: start your own blog, and have the planet aggregate it.

Or there's Yahoo! Pipes, described by Bill Clementson here:
http://bc.tech.coop/blog/081206.html

The concept's the same, at any rate: instead of a single community blog,
there's a single blog aggregator, fed by multiple personal blogs.

frank


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Community blog? (was: Re: How to profile a serverimage?)

cedreek
>
> Well, I'd follow your blog, for one. But http://planet.squeak.org/ is pretty
> darn cool: start your own blog, and have the planet aggregate it.

I'd better use our own tool, a kind of mix between blog and wiki...
using rights to allow some other people to modify/complete some
posts... I think we have it already minus some particularities, it's
more a question of organization.

One thing I'll find important is to define a common set of tags
(topics, level of completion, importance, documentation type,
deprecation (st version concerned) etc...).

Voting on relevance cound be nice too...

Having proper developper/person profile would be of high interest to
me too... so that a beginner can find post written by beginner,
tutorial for beginners, etc... If you "like" someone, you can get his
posts/modifs/comments plus the ones of people that are "similar" to
him...

...

Just my 2 cents ;)


>
> Or there's Yahoo! Pipes, described by Bill Clementson here:
> http://bc.tech.coop/blog/081206.html
>
> The concept's the same, at any rate: instead of a single community blog,
> there's a single blog aggregator, fed by multiple personal blogs.
>
> frank
>
>
>



--
Cédrick

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Community blog? (was: Re: How to profile a serverimage?)

Bert Freudenberg
In reply to this post by Frank Shearar

On 04.03.2009, at 10:01, Frank Shearar wrote:

>  http://planet.squeak.org/ is pretty
> darn cool: start your own blog, and have the planet aggregate it.
>
> The concept's the same, at any rate: instead of a single community  
> blog,
> there's a single blog aggregator, fed by multiple personal blogs.


It would be more useful if the individual feeds were only for those  
blog posts tagged "squeak" ... for my taste too many non-squeak  
related posts make it to the planet. Most blog engines allow to tag  
posts, and to get feeds for specific tags only. Those filtered feeds  
should get aggregated, not every "guitar hero" blurb ;)

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: How to profile a server image?

David T. Lewis
In reply to this post by johnmci
On Tue, Mar 03, 2009 at 09:06:16PM -0800, John M McIntosh wrote:

> A long time ago I suggested that you could track CPU usage, or  
> dispatch clock time in
> Interpreter>>transferTo: aProc  since that still is the only place a  
> transfer switch occurs between processes.
> You could collect more things too, like network traffic etc.
> I've always thought the benefit is that you don't have some ugly high  
> priority watcher task thundering about
> creating garbage and leaving foot prints in the cake...
>
>
> http://lists.squeakfoundation.org/pipermail/squeak-dev/2001-March/015945.html

Wow, back then the biggest impediment to progress was your 14400 baud
modem ("just try doing uploads etc at 14400 baud") !

;)



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Community blog?

Göran Krampe
In reply to this post by Bert Freudenberg
Hi!

Bert Freudenberg wrote:
> It would be more useful if the individual feeds were only for those blog
> posts tagged "squeak" ... for my taste too many non-squeak related posts
> make it to the planet. Most blog engines allow to tag posts, and to get
> feeds for specific tags only. Those filtered feeds should get
> aggregated, not every "guitar hero" blurb ;)

We just set up a Venus aggregator here at MSC - Venus is the enhanced
version of Planet that has filtering capabilities. Then you can filter
on categories/tags etc.

Furthermore - a blog aggregator (or community blog - but a blog
aggregator is IMHO smarter) serves a different purpose than a wiki.

I would though consider setting up a new "purged" wiki that "starts
over" from scratch and perhaps tries to limits itself in what it
documents - like perhaps from a given version of Squeak and forward.

regards, Göran


Reply | Threaded
Open this post in threaded view
|

RE: [squeak-dev] Community blog? (was: Re: How to profile a serverimage?)

Sebastian Sastre-2
In reply to this post by Andreas.Raab
+1. blog is the way to go.

It *could* be st based but it *hasn't* necessarily to be st based.

Design matters so it *hasn't* to hurt the eye when you see it. Today that could be more important than bloating it with features.

cheers,
sebastian

> -----Mensaje original-----
> De: [hidden email]
> [mailto:[hidden email]] En
> nombre de Andreas Raab
> Enviado el: Tuesday, March 03, 2009 23:26
> Para: The general-purpose Squeak developers list
> Asunto: [squeak-dev] Community blog? (was: Re: How to profile
> a serverimage?)
>
> Igor Stasenko wrote:
> > There is a wiki page, already dedicated to it
> > http://wiki.squeak.org/squeak/1799
> >
> > Or , maybe its worth create a new page 'Profiling in Squeak' .. or
> > give it more appropriate name
>
> Now up at http://wiki.squeak.org/squeak/6122
>
> Which reminds me: I had forgotten how much I hate the Swiki.
> It is ugly,
> horribly conflated, and effectively unusable. Should we
> replace the damn
> thing with a community blog instead? I think this might be a
> better way
> of dealing with the information overload - you get dated,
> tagged entry
> and if we keep this open for pretty much every member of the
> community
> (using the "standard" username/password from the Swiki) we
> could use it
> much the same.
>
> I'd be more than willing to write up my post as a blog
> article instead.
> I just don't have a blog and even if I had I doubt many
> people would use
> it. A community blog could be a nice, lively place to post
> your thoughts
> in a bit more organized manner and would make an attractive
> target for
> people who just want to know what's going on in the world of Squeak.
>
> Cheers,
>    - Andreas
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: How to profile a server image?

Juan Vuletich-4
In reply to this post by Andreas.Raab
Hi Andreas,

Andreas Raab wrote:

> Juan Vuletich wrote:
>> I understand that for a server having an variable (and big) number of
>> processes it is not useful. But for our case, an application with a
>> small and fixed set of processes, the first question we want to
>> answer is "which is the process using all the cpu?". Please see the
>> message I just sent on this thread to see an example of what I want.
>
> Okay, I cracked ;-) Attached you'll find patches for a message tally
> version which does per-process reporting if so desired. I've moved
> this out of the arguments and into class variables so you get/set
> either priority or preference via, e.g.:
>
>   MessageTally spyPriority: <new priority>
>   MessageTally showProcesses: <true/false>
>
> The defaults are such that the priority is TimerPriority-1 and
> showProcesses is on. With it, your example gives the result shown below.
>
> Let me know if this works for you (or anyone else). Comments welcome.
>
> Cheers,
>   - Andreas
Thank you! After wasting many hours on the idea of attaching the
firstContext to each process, I also realized it is not necessary at
all. But before I could get the tallies properly built, I went to sleep,
and you did it! Thanks! I found a small bug, though. You forgot to
actually use the class var SpyPriority.

The attached change is based on yours, but with a few differences (some
of them you might like, some others you might not like :)

- If you tally a single process via #spyEvery:onProcess:forMilliseconds:
(for example using the option in the ProcessBrowser) you'll get bogus
results, as all tallies are captured as if they belonged to the observed
process. I fixed it. This one is important.

- I left the old #spyOn: for spying on a single process, with the fix I
just mentioned to report realistic results. I added #spyAllOn: to spy on
all the running processes. I believe many times one might want to spy on
just one process.

- I removed the SpyPriority classVar. If spying on all processes, I use
a really high priority. If spying on single process, I use a slightly
higher priority than his (using a a really high priority would not hurt,
though). This is just a matter of taste.

- I removed the old ObservedProcess class var, as it is no longer necessary.

- Allowed for more visible tabs (just cosmetic).

- Show nodes using more than 1% (instead of 2%). Not very important.

- Modified the menu options in World menu / Debug, to allow for both
tallyin the UI or all the system, and to make this clear.

That's all. I hope you and others find it useful.

Cheers,
Juan Vuletich

'From Squeak3.10.2 of ''5 June 2008'' [latest update: #7179] on 4 March 2009 at 10:44:49 am'!
Magnitude subclass: #MessageTally
        instanceVariableNames: 'class method tally receivers senders time gcStats maxClassNameSize maxClassPlusSelectorSize maxTabs process '
        classVariableNames: 'DefaultPollPeriod ObservedProcess Timer ShowProcesses '
        poolDictionaries: ''
        category: 'System-Tools'!

!MessageTally methodsFor: 'comparing' stamp: 'ar 3/3/2009 19:36'!
= aMessageTally

        self species == aMessageTally species ifFalse: [^ false].
        ^ aMessageTally method == method and:[aMessageTally process == process]! !

!MessageTally methodsFor: 'initialize-release' stamp: 'jmv 3/4/2009 10:35'!
close

        (Timer isMemberOf: Process) ifTrue: [Timer terminate].
        Timer := nil.
        class := method := tally := receivers := nil! !

!MessageTally methodsFor: 'initialize-release' stamp: 'jmv 3/4/2009 10:40'!
spyAllEvery: millisecs on: aBlock
        "Create a spy and spy on the given block at the specified rate."
        "Spy all the system processes"

        | myDelay startTime time0 observedProcess |
        (aBlock isMemberOf: BlockContext)
                ifFalse: [self error: 'spy needs a block here'].
        self class: aBlock receiver class method: aBlock method.
                "set up the probe"
        myDelay := Delay forMilliseconds: millisecs.
        time0 := Time millisecondClockValue.
        gcStats := SmalltalkImage current getVMParameters.
        Timer := [
                [true] whileTrue: [
                        startTime := Time millisecondClockValue.
                        myDelay wait.
                        observedProcess := Processor preemptedProcess.
                        self tally: observedProcess suspendedContext
                                in: (ShowProcesses ifTrue: [observedProcess])
                                "tally can be > 1 if ran a long primitive"
                                by: (Time millisecondClockValue - startTime) // millisecs].
                nil] newProcess.
        Timer priority: Processor timingPriority-1.
                "activate the probe and evaluate the block"
        Timer resume.
        ^ aBlock ensure: [
                "Collect gc statistics"
                SmalltalkImage current getVMParameters keysAndValuesDo: [ :idx :gcVal |
                        gcStats at: idx put: (gcVal - (gcStats at: idx))].
                "cancel the probe and return the value"
                Timer terminate.
                time := Time millisecondClockValue - time0]! !

!MessageTally methodsFor: 'initialize-release' stamp: 'jmv 3/4/2009 10:41'!
spyEvery: millisecs on: aBlock
        "Create a spy and spy on the given block at the specified rate."
        "Spy only on the active process (in which aBlock is run)"

        | myDelay startTime time0 observedProcess |
        (aBlock isMemberOf: BlockContext)
                ifFalse: [self error: 'spy needs a block here'].
        self class: aBlock receiver class method: aBlock method.
                "set up the probe"
        observedProcess _ Processor activeProcess.
        myDelay := Delay forMilliseconds: millisecs.
        time0 := Time millisecondClockValue.
        gcStats := SmalltalkImage current getVMParameters.
        Timer := [
                [true] whileTrue: [
                        Processor preemptedProcess == observedProcess ifTrue: [
                                startTime _ Time millisecondClockValue.
                                myDelay wait.
                                self tally: observedProcess suspendedContext
                                        in: observedProcess
                                        "tally can be > 1 if ran a long primitive"
                                        by: (Time millisecondClockValue - startTime) // millisecs]].
                nil] newProcess.
        Timer priority: (observedProcess priority + 1 min: Processor highestPriority).
                "activate the probe and evaluate the block"
        Timer resume.
        ^ aBlock ensure: [
                "Collect gc statistics"
                SmalltalkImage current getVMParameters keysAndValuesDo: [ :idx :gcVal |
                        gcStats at: idx put: (gcVal - (gcStats at: idx))].
                "cancel the probe and return the value"
                Timer terminate.
                time := Time millisecondClockValue - time0]! !

!MessageTally methodsFor: 'initialize-release' stamp: 'jmv 3/4/2009 10:42'!
spyEvery: millisecs onProcess: aProcess forMilliseconds: msecDuration
        "Create a spy and spy on the given process at the specified rate."
        | myDelay startTime time0 endTime sem observedProcess |
        (aProcess isKindOf: Process)
                ifFalse: [self error: 'spy needs a Process here'].
        self class: aProcess suspendedContext receiver class method: aProcess suspendedContext method.
        "set up the probe"
        observedProcess := aProcess.
        myDelay := Delay forMilliseconds: millisecs.
        time0 := Time millisecondClockValue.
        endTime := time0 + msecDuration.
        sem := Semaphore new.
        gcStats := SmalltalkImage current getVMParameters.
        Timer := [
                        [
                                startTime _ Time millisecondClockValue.
                                        Processor preemptedProcess == observedProcess ifTrue: [
                                        myDelay wait.
                                        self tally: observedProcess suspendedContext
                                                in: observedProcess
                                                by: Time millisecondClockValue - startTime // millisecs].
                                startTime < endTime
                        ] whileTrue.
                        sem signal
                ] forkAt: (observedProcess priority + 1 min: Processor highestPriority).
        "activate the probe and wait for it to finish"
        sem wait.
        "Collect gc statistics"
        SmalltalkImage current getVMParameters keysAndValuesDo: [ :idx :gcVal |
                gcStats at: idx put: (gcVal - gcStats at: idx)].
        time := Time millisecondClockValue - time0! !

!MessageTally methodsFor: 'printing' stamp: 'ar 3/3/2009 19:43'!
fullPrintOn: aStream tallyExact: isExact orThreshold: perCent
        | threshold |  
        isExact ifFalse: [threshold _ (perCent asFloat / 100 * tally) rounded].
        aStream nextPutAll: '**Tree**'; cr.
        self rootPrintOn: aStream
                total: tally
                totalTime: time
                tallyExact: isExact
                orThreshold: threshold.
        aStream nextPut: Character newPage; cr.
        aStream nextPutAll: '**Leaves**'; cr.
        self leavesPrintOn: aStream
                tallyExact: isExact
                orThreshold: threshold! !

!MessageTally methodsFor: 'printing' stamp: 'ar 3/3/2009 19:47'!
rootPrintOn: aStream total: total totalTime: totalTime tallyExact: isExact orThreshold: threshold
        | sons groups |
        ShowProcesses ifFalse:[
                ^self treePrintOn: aStream
                        tabs: OrderedCollection new
                        thisTab: ''
                        total: total
                        totalTime: totalTime
                        tallyExact: isExact
                        orThreshold: threshold.
        ].
        sons := isExact ifTrue: [receivers] ifFalse: [self sonsOver: threshold].
        groups := sons groupBy:[:aTally| aTally process] having:[:g| true].
        groups do:[:g|
                sons := g asSortedCollection.
                aStream nextPutAll: '--------------------------------'; cr.
                aStream nextPutAll: 'Process: ', g anyOne process browserPrintString; cr.
                aStream nextPutAll: '--------------------------------'; cr.
                (1 to: sons size) do:[:i |
                        (sons at: i)
                                treePrintOn: aStream
                                tabs: OrderedCollection new
                                thisTab: ''
                                total: total
                                totalTime: totalTime
                                tallyExact: isExact
                                orThreshold: threshold].
        ].! !

!MessageTally methodsFor: 'reporting' stamp: 'jmv 3/4/2009 09:27'!
report: strm
        "Print a report, with cutoff percentage of each element of the tree
        (leaves, roots, tree), on the stream, strm."

        self report: strm cutoff: 1! !

!MessageTally methodsFor: 'tallying' stamp: 'jmv 3/4/2009 10:36'!
tally: context by: count
        "Explicitly tally the specified context and its stack."
        | sender |
       
        "Add to this node if appropriate"
        context method == method ifTrue: [^self bumpBy: count].
       
        "No sender? Add new branch to the tree."
        (sender := context home sender)ifNil: [
                ^ (self bumpBy: count) tallyPath: context by: count].
       
        "Find the node for the sending context (or add it if necessary)"
        ^ (self tally: sender by: count) tallyPath: context by: count! !

!MessageTally methodsFor: 'tallying' stamp: 'jmv 3/4/2009 09:42'!
tally: context in: aProcess by: count
        "Explicitly tally the specified context and its stack."
        | sender |

        "Add to this node if appropriate"
        context method == method ifTrue: [^self bumpBy: count].
       
        "No sender? Add new branch to the tree."
        (sender := context home sender) ifNil: [
                ^ (self bumpBy: count) tallyPath: context in: aProcess by: count].
       
        "Find the node for the sending context (or add it if necessary)"
        ^ (self tally: sender in: aProcess by: count) tallyPath: context in: aProcess by: count! !

!MessageTally methodsFor: 'tallying' stamp: 'jmv 3/4/2009 10:36'!
tallyPath: context by: count
        | aMethod path |
        aMethod :=context method.
       
        "Find the correct child (if there)"
        receivers do: [ :oldTally |
                oldTally method == aMethod ifTrue: [path := oldTally]].
       
        "Add new child if needed"
        path ifNil: [
                path := MessageTally new class: context receiver class method: aMethod.
                receivers := receivers copyWith: path].
       
        ^ path bumpBy: count! !

!MessageTally methodsFor: 'tallying' stamp: 'jmv 3/4/2009 10:38'!
tallyPath: context in: aProcess by: count
        | aMethod path |
        aMethod := context method.
       
        "Find the correct child (if there)"
        receivers do: [ :oldTally |
                (oldTally method == aMethod and: [oldTally process == aProcess])
                        ifTrue: [path := oldTally]].
               
        "Add new child if needed"
        path ifNil:[
                path := MessageTally new class: context receiver class method: aMethod;
                        process: aProcess;
                        maxClassNameSize: maxClassNameSize;
                        maxClassPlusSelectorSize: maxClassPlusSelectorSize;
                        maxTabs: maxTabs.
                receivers := receivers copyWith: path].

        ^ path bumpBy: count! !

!MessageTally methodsFor: 'private' stamp: 'ar 3/3/2009 19:29'!
process
        ^process! !

!MessageTally methodsFor: 'private' stamp: 'ar 3/3/2009 19:29'!
process: aProcess
        process := aProcess! !


!MessageTally class methodsFor: 'defaults' stamp: 'jmv 3/2/2009 12:32'!
defaultMaxTabs
        "Return the default number of tabs after which leading white space is compressed"
        ^120! !

!MessageTally class methodsFor: 'defaults' stamp: 'jmv 3/4/2009 10:29'!
showProcesses
        "Indicates whether to show each process separately or cumulatively.
        For example, compare the spy results of the following with both values:
       
                [1000 timesRepeat: [3.14159 printString. Processor yield]] fork.
                [1000 timesRepeat: [30 factorial. Processor yield]] fork.
                [1000 timesRepeat: [30 factorial. Processor yield]] fork.
                MessageTally spyAllOn: [ (Delay forMilliseconds: 100) wait]

        "
        ^ShowProcesses! !

!MessageTally class methodsFor: 'defaults' stamp: 'jmv 3/4/2009 10:29'!
showProcesses: aBool
        "Indicates whether to show each process separately or cumulatively.
        For example, compare the spy results of the following with both values:
       
                [1000 timesRepeat: [3.14159 printString. Processor yield]] fork.
                [1000 timesRepeat: [30 factorial. Processor yield]] fork.
                [1000 timesRepeat: [30 factorial. Processor yield]] fork.
                MessageTally spyAllOn: [ (Delay forMilliseconds: 100) wait]

        "
        ShowProcesses := aBool.! !

!MessageTally class methodsFor: 'spying' stamp: 'jmv 3/4/2009 10:42'!
spyAllOn: aBlock
        "Spy on all the processes in the system
       
        [1000 timesRepeat: [3.14159 printString. Processor yield]] fork.
        [1000 timesRepeat: [20 factorial. Processor yield]] fork.
        [1000 timesRepeat: [20 factorial. Processor yield]] fork.
        MessageTally spyAllOn: [ (Delay forMilliseconds: 100) wait]
       
        "
        | node result |
        node := self new.
        result := node spyAllEvery: self defaultPollPeriod on: aBlock.
        (StringHolder new contents: (String streamContents: [:s | node report: s; close]))
                openLabel: 'Spy Results'.
        ^ result! !

!MessageTally class methodsFor: 'class initialization' stamp: 'jmv 3/4/2009 09:24'!
initialize
        "MessageTally initialize"
        "By default, show each process separately"
        ShowProcesses := true! !


!TheWorldMenu methodsFor: 'commands' stamp: 'jmv 3/4/2009 10:43'!
startMessageTally
        "Tally on all the processes in the system, and not only the UI"
       
        (self confirm: 'MessageTally all the processes in
the system, until the mouse pointer
goes to the top of the screen') ifTrue: [
                MessageTally spyAllOn: [
                        [Sensor peekMousePt y > 0] whileTrue: [World doOneCycle]]]! !

!TheWorldMenu methodsFor: 'construction' stamp: 'jmv 3/4/2009 10:44'!
debugMenu

        | menu |

        menu _ self menu: 'debug...'.
        self fillIn: menu from: {
                { 'inspect world' . { #myWorld . #inspect } }.
                { 'explore world' . { #myWorld . #explore } }.
                { 'inspect model' . { self . #inspectWorldModel } }.
                        " { 'talk to world...' . { self . #typeInMessageToWorld } }."
                { 'MessageTally all Processes' . { self . #startMessageTally } }.
                { 'MessageTally UI and browse' . { self . #startThenBrowseMessageTally } }.
                { 'open process browser' . { self . #openProcessBrowser } }.
                nil.
                        "(self hasProperty: #errorOnDraw) ifTrue:  Later make this come up only when needed."
                { 'start drawing again' . { #myWorld . #resumeAfterDrawError } }.
                { 'start stepping again' . { #myWorld . #resumeAfterStepError } }.
                nil.
                { 'call #tempCommand' . { #myWorld . #tempCommand } }.
                { 'define #tempCommand' . { #myWorld . #defineTempCommand } }.
        }.
        self haltOnceEnabled
                ifTrue: [menu
                                add: 'disable halt/inspect once' translated
                                target: menu
                                action: #clearHaltOnce]
                ifFalse: [menu
                                add: 'enable halt/inspect once' translated
                                target: menu
                                action: #setHaltOnce].
        ^menu
        ! !

!TheWorldMenu methodsFor: '*Tools' stamp: 'jmv 3/4/2009 10:43'!
startThenBrowseMessageTally
        "Tally only the UI process"
       
        (self confirm: 'MessageTally the UI process until the
mouse pointer goes to the top of the screen')
                ifTrue: [TimeProfileBrowser
                                onBlock: [[Sensor peekMousePt y > 10]
                                                whileTrue: [World doOneCycle]]]! !

MessageTally initialize!
Magnitude subclass: #MessageTally
        instanceVariableNames: 'class method process tally receivers senders time gcStats maxClassNameSize maxClassPlusSelectorSize maxTabs'
        classVariableNames: 'DefaultPollPeriod ShowProcesses Timer'
        poolDictionaries: ''
        category: 'System-Tools'!


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Community blog? (was: Re: How to profile a server image?)

Eliot Miranda-2
In reply to this post by Andreas.Raab


On Tue, Mar 3, 2009 at 6:25 PM, Andreas Raab <[hidden email]> wrote:
Igor Stasenko wrote:
There is a wiki page, already dedicated to it
http://wiki.squeak.org/squeak/1799

Or , maybe its worth create a new page 'Profiling in Squeak' .. or
give it more appropriate name

Now up at http://wiki.squeak.org/squeak/6122

Which reminds me: I had forgotten how much I hate the Swiki. It is ugly, horribly conflated, and effectively unusable.

Wikis are like gardens.  Untended they grow like weeds.  Unless one has a writership with an active minority of editors, who spend time trying to reorganize the wiki as it sprawls one may well end up with something effectively unusable.  But as a form for organizing growing reference material IMO they can't be beat; look at Wikipedia.  That is a superb wiki.  The VisualWorks wiki was pretty good until its lack of spam protection and lack of long-term hosting killed it dead.  Couldn't we have a community project to reorganize the wiki?  Its the right form, its just a little overgrown right now.
 
Should we replace the damn thing with a community blog instead?

Different form for different uses.  The Squeak daily news works as a blog.  I can't see how a blog would scale to hold the reference material for Galaxy Squeak.


I think this might be a better way of dealing with the information overload - you get dated, tagged entry and if we keep this open for pretty much every member of the community (using the "standard" username/password from the Swiki) we could use it much the same.

I'd be more than willing to write up my post as a blog article instead. I just don't have a blog and even if I had I doubt many people would use it. A community blog could be a nice, lively place to post your thoughts in a bit more organized manner and would make an attractive target for people who just want to know what's going on in the world of Squeak.

Cheers,
 - Andreas





Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Community blog?

Simon Michael
In reply to this post by Bert Freudenberg
On planet.squeak.org, I use squeak/smalltalk-specific topic feeds when I
can find them, and I omit blogs which seem less than 50% squeak related.
I usually find the result on-topic enough, with occasional enjoyable
diversions to euro board games etc. My model is the Debian, Gnome and
Ubuntu planets which are about building a strong community, not just
propagating technical discussion.

But, just send a patch or suggestion implementing the changes you want.
If a particular blog is too off-topic and there's no topic feed, you
could try contacting the author here and talking them into line.


123