[7.8] NetClient class>>defaultTimeoutValue

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

[7.8] NetClient class>>defaultTimeoutValue

Boris Popov, DeepCove Labs (SNN)

What’s the point NetClient class>>defaultTimeoutValue given the below? It may be helpful to change that to a class instance variable and let subclasses define their own default timeouts.

 

NetClient class>>defaultTimeout

                ^DefaultTimeout isNil

                                ifTrue: [ DefaultTimeout := self defaultTimeoutValue ]

                                ifFalse: [ DefaultTimeout ]

 

-Boris

Sr. Software Engineer

DeepCove Labs

4th floor, 595 Howe Street

Vancouver, BC V6C 2T5

Canada

 


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [7.8] NetClient class>>defaultTimeoutValue

Kogan, Tamara

It makes sense.  Created for 7.10:

65132: "Change NetClient shared variables (delay/timeout/retry) to class instance variables"

 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Boris Popov, DeepCove Labs
Sent: Friday, April 06, 2012 8:18 AM
To: [hidden email]
Subject: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

What’s the point NetClient class>>defaultTimeoutValue given the below? It may be helpful to change that to a class instance variable and let subclasses define their own default timeouts.

 

NetClient class>>defaultTimeout

                ^DefaultTimeout isNil

                                ifTrue: [ DefaultTimeout := self defaultTimeoutValue ]

                                ifFalse: [ DefaultTimeout ]

 

-Boris

Sr. Software Engineer

DeepCove Labs

4th floor, 595 Howe Street

Vancouver, BC V6C 2T5

Canada

 


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [7.8] NetClient class>>defaultTimeoutValue

Reinout Heeck-2
On 4/9/2012 5:35 PM, Kogan, Tamara wrote:

It makes sense.  Created for 7.10:

65132: "Change NetClient shared variables (delay/timeout/retry) to class instance variables"


This is surely a mistake, it ought to read "remove global variables".


Here at Soops we have serious problems with the various frameworks that use globals, whether for default values (as exemplified here to be allowed to vary) or for current values (eg Soap bindings). We often need to have multiple projects in a single image for purposes of refactoring, however the overuse of globals prevents us from running these projects simultaneously in a single image.

So this AR should not ask to morph class shareds into class ivars, instead it should ask to morph them into hard-coded methods (that can be overridden in subclasses).


Another way of putting this: if the contents of those shared vars is allowed to vary I can no longer use them across multiple projects. We could declare these variables as constant but (IMO) the prevailing Smalltalk idiom for that is to use methods that return a constant value instead.


My 2c.

Reinout
-------









 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: [hidden email] [[hidden email]] On Behalf Of Boris Popov, DeepCove Labs
Sent: Friday, April 06, 2012 8:18 AM
To: [hidden email]
Subject: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

What’s the point NetClient class>>defaultTimeoutValue given the below? It may be helpful to change that to a class instance variable and let subclasses define their own default timeouts.

 

NetClient class>>defaultTimeout

                ^DefaultTimeout isNil

                                ifTrue: [ DefaultTimeout := self defaultTimeoutValue ]

                                ifFalse: [ DefaultTimeout ]

 

-Boris

Sr. Software Engineer

DeepCove Labs

4th floor, 595 Howe Street

Vancouver, BC V6C 2T5

Canada

 



_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [7.8] NetClient class>>defaultTimeoutValue

Kogan, Tamara

Reinout,

 

Here is the plan for AR#65132.

 

In 7.9 we have already added NetPISettings for NetProtocolInterpreter classes and HttpSettings for HttpProtocolInterpreter.

We will add settings classes for each client PI and move delay/timeout/retry to the settings as class ivars.

 

To set global timeout value for HttpClient:  HttpSettings defaultTimeout:  1000.

For an instance: HttpClient new settings timeout: 1000.

 

IMAPClient:

IMAPSettings defaultTimeout:  1000.

IMAPClient new settings timeout: 1000.

 

WsdlClient

WsdlClient new transportClient settings timeout: 1000.

(mySettings := HttpSetting new) timeout: 1000.

(Client1 := WsdlClient new) transportClient settings: mySettings.

(Client2 := WsdlClient new) transportClient settings: mySettings.

 

Is there any problem with this solution for your applications?

 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: Reinout Heeck [mailto:[hidden email]]
Sent: Wednesday, April 11, 2012 10:34 AM
To: [hidden email]
Cc: Kogan, Tamara; Boris Popov, DeepCove Labs
Subject: Re: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

On 4/9/2012 5:35 PM, Kogan, Tamara wrote:

It makes sense.  Created for 7.10:

65132: "Change NetClient shared variables (delay/timeout/retry) to class instance variables"


This is surely a mistake, it ought to read "remove global variables".


Here at Soops we have serious problems with the various frameworks that use globals, whether for default values (as exemplified here to be allowed to vary) or for current values (eg Soap bindings). We often need to have multiple projects in a single image for purposes of refactoring, however the overuse of globals prevents us from running these projects simultaneously in a single image.

So this AR should not ask to morph class shareds into class ivars, instead it should ask to morph them into hard-coded methods (that can be overridden in subclasses).


Another way of putting this: if the contents of those shared vars is allowed to vary I can no longer use them across multiple projects. We could declare these variables as constant but (IMO) the prevailing Smalltalk idiom for that is to use methods that return a constant value instead.


My 2c.

Reinout
-------










 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: [hidden email] [[hidden email]] On Behalf Of Boris Popov, DeepCove Labs
Sent: Friday, April 06, 2012 8:18 AM
To: [hidden email]
Subject: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

What’s the point NetClient class>>defaultTimeoutValue given the below? It may be helpful to change that to a class instance variable and let subclasses define their own default timeouts.

 

NetClient class>>defaultTimeout

                ^DefaultTimeout isNil

                                ifTrue: [ DefaultTimeout := self defaultTimeoutValue ]

                                ifFalse: [ DefaultTimeout ]

 

-Boris

Sr. Software Engineer

DeepCove Labs

4th floor, 595 Howe Street

Vancouver, BC V6C 2T5

Canada

 




_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [7.8] NetClient class>>defaultTimeoutValue

Reinout Heeck-2
On 4/11/2012 5:15 PM, Kogan, Tamara wrote:

Reinout,

 

Here is the plan for AR#65132.

 

In 7.9 we have already added NetPISettings for NetProtocolInterpreter classes and HttpSettings for HttpProtocolInterpreter.

We will add settings classes for each client PI


So far so good, this provides the mechanisms we need.



But then you say

and move delay/timeout/retry to the settings as class ivars.


which are global variables.
Moreover you treat them as variable and provide methods to make them vary:

 

To set global timeout value for HttpClient:  HttpSettings defaultTimeout:  1000.


So you signal to future generations that it is fine to alter the contents of these globals.

Consider a scenario where one developer makes a client for some Google.com service and another developer creates a client for some Amazon.com service.
The developer of the Amazon service encountered some problems so she decides to increase some timeout. The easiest way to do this to use the API you provided for the globals, so that is the one she uses.

Now when Soops decides to use both these clients in a single image we find that /unrelated/ code is affected.
In effect Cincom is providing a system that works in small projects but fails when small projects are composed into a bigger one.




The way my mind sees this problem is in terms of semiotics:
the alterations you propose /signal/ to future developers that altering the globals is the preferred way because 1) that requires the least code and 2) you imply approval by explicitly providing setters for those variables.

There are many ways to make those variables non-variable, the easiest one I described in my previous mail: default values should come from methods instead of variables. This way both 1) and 2) above are settled because there is only one way to alter the timeout (provide mySettings).
By doing it this way Soops can reliably import other clients without having to run into unexpected alterations to existing net client behavior.





Some other nitpicks: 

IMAPClient new settings timeout: 1000.


That violates encapsulation, consider
    IMAPClient new timeout: 1000

 


WsdlClient new transportClient settings timeout: 1000.


ditto: consider removing the #settings send.




(mySettings := HttpSetting new) timeout: 1000.

(Client1 := WsdlClient new) transportClient settings: mySettings.

(Client2 := WsdlClient new) transportClient settings: mySettings.


At Soops we went through various paradigms regarding settings objects, you can make a settings object 'part' of a client (as you seem to suggest above). We found that that creates all kinds of confusion: is this aspect part of some setting object or part of the state of a client?

So we moved to settings objects as factories:
  client1 := mySettings newWsdlClient.

we abandoned that pretty swiftly, it felt like it solved nothing.


Nowadays we experiment with 'simple' objects, if a client needs a timeout it will 'simply' have a variable named 'timeout'.
Settings objects are ephemeral, the client will not retain a reference to a settings object. Instead a settings object will #applyTo: a client instance.
This way settings can be composed by the re-user instead of being of fixed shape decided by the library provider.

client := Client new.
myTimoutPreferences applyTo: client.
debuggingAids applyTo: client.

etc...

If someone knows a commonly used name for this pattern I would like to hear it!



 

Is there any problem with this solution for your applications?


Many thanks for describing the plans!


Reinout
-------




 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: Reinout Heeck [[hidden email]]
Sent: Wednesday, April 11, 2012 10:34 AM
To: [hidden email]
Cc: Kogan, Tamara; Boris Popov, DeepCove Labs
Subject: Re: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

On 4/9/2012 5:35 PM, Kogan, Tamara wrote:

It makes sense.  Created for 7.10:

65132: "Change NetClient shared variables (delay/timeout/retry) to class instance variables"


This is surely a mistake, it ought to read "remove global variables".


Here at Soops we have serious problems with the various frameworks that use globals, whether for default values (as exemplified here to be allowed to vary) or for current values (eg Soap bindings). We often need to have multiple projects in a single image for purposes of refactoring, however the overuse of globals prevents us from running these projects simultaneously in a single image.

So this AR should not ask to morph class shareds into class ivars, instead it should ask to morph them into hard-coded methods (that can be overridden in subclasses).


Another way of putting this: if the contents of those shared vars is allowed to vary I can no longer use them across multiple projects. We could declare these variables as constant but (IMO) the prevailing Smalltalk idiom for that is to use methods that return a constant value instead.


My 2c.

Reinout
-------










 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: [hidden email] [[hidden email]] On Behalf Of Boris Popov, DeepCove Labs
Sent: Friday, April 06, 2012 8:18 AM
To: [hidden email]
Subject: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

What’s the point NetClient class>>defaultTimeoutValue given the below? It may be helpful to change that to a class instance variable and let subclasses define their own default timeouts.

 

NetClient class>>defaultTimeout

                ^DefaultTimeout isNil

                                ifTrue: [ DefaultTimeout := self defaultTimeoutValue ]

                                ifFalse: [ DefaultTimeout ]

 

-Boris

Sr. Software Engineer

DeepCove Labs

4th floor, 595 Howe Street

Vancouver, BC V6C 2T5

Canada

 




_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

efficient, complete and fast OrderedSet

Pierre-34
Hy all,
I need to create and manipulate a big collection of ordered objects without duplicates.
I created a subclass of OrderedCollection for which I redefined some few methods as #addLast:
addLast: newObject
    "Add newObject to the end of the receiver.  Answer newObject."
    (self includes: newObject)
        ifFalse: [^super addLast: newObject ].
    ^newObject
This work but it's very time consuming.
I know that Set has been optimized, and I'd like to know if anybody already has created a subclass of Set that can respond to all methods of OrderedCollection??
(I don't know if OrderedSet is optimized, but it doesn't provide all the OrderedCollection methods)
Thank's for your help. All the best,

    Pierre

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [7.8] NetClient class>>defaultTimeoutValue

Steven Kelly
In reply to this post by Reinout Heeck-2

Thanks Reinout, I hadn’t thought of the problem of settings like that before! You’re clearly right, and I find that surprising since the solution goes against several principles I’ve found useful:

1)      where possible, it’s good to move things from being code to being data

2)      don’t embed constants in code, turn them into variables that are initialized

3)      convention over configuration

I think I’ll be a better programmer when I can find a new way to understand the deeper truths behind those principles so they aren’t in conflict with your solution! Or then maybe I agree with you on the problem, but not necessarily on the solution?

 

The first problem I see with your solution is minor: what will happen when somebody wants a different value, and doesn’t think things through: rather than adding a line to their own class to change the default value:

 

MyClass class>>initialize

   HttpSettings defaultTimeout:  1000

 

they’ll do the simplest thing that can possibly work: override the hard-coded constant in the method:

 

HttpSettings class>>defaultTimeout

   ^1000 "VW used 3000, but we want less"

 

Obviously that’s not good. Instead, you suggest one approach would be subclassing:

 

MyHttpSettings class>>defaultTimeout

   ^1000

 

I don’t think subclassing should be used as a way of providing new values for a single setting. The idea of having this as a setting is to make changing it lightweight, and adding a class is quite heavyweight. A class instance variable approach would be similar (although I don’t see why you think it’s worse). I’d prefer to see code that instantiates an HttpClient refer to HttpClient, rather than MyHttpClient – at least until the subclass actually behave differently in something more than aspects that are considered as settings.

 

I wouldn’t imagine there would be many pieces of code that would instantiate an HttpClient, so maybe the simplest practice would be to specify the timeout, where it is known the default isn’t good (of course this opens up the question of how much we trust Cincom’s defaults vs. how much we want to specify every single setting):

 

myClient := HttpClient new timeout: 1000.

 

Obviously if there are many such occurrences, all with the same settings, they can be moved to a factory method in our own class, or as an extension in HttpClient:

 

myClient := HttpClient newWithMySettings.

 

For more complex cases, your #apply’able Settings objects sound like a good solution.

 

So, the base VW would have a single, constant global value for the setting, and offer no mechanism for providing alternative default values within the class or its subclasses. The only mechanism would be instance-side, and if a team found duplication creeping into their code or the values it used, they would create their own mechanisms to avoid it. There would be convention over configuration in the base, and as teams wanted a different convention, they would implement their own so that within their own code there would be their own convention over configuration.

 

To make the constant global value less likely to be changed or overridden, I’d suggest a Shared Variable with an initialize and constant: true. I think people wouldn’t override that as easily as they would a method.

 

This approach doesn’t break the principles I listed above, but I think it still solves the problems you identified. Thoughts?

 

Steve

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Reinout Heeck
Sent: 12. huhtikuuta 2012 17:16
To: [hidden email]
Subject: Re: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

On 4/11/2012 5:15 PM, Kogan, Tamara wrote:

Reinout,

 

Here is the plan for AR#65132.

 

In 7.9 we have already added NetPISettings for NetProtocolInterpreter classes and HttpSettings for HttpProtocolInterpreter.

We will add settings classes for each client PI


So far so good, this provides the mechanisms we need.



But then you say


and move delay/timeout/retry to the settings as class ivars.


which are global variables.
Moreover you treat them as variable and provide methods to make them vary:


 

To set global timeout value for HttpClient:  HttpSettings defaultTimeout:  1000.


So you signal to future generations that it is fine to alter the contents of these globals.

Consider a scenario where one developer makes a client for some Google.com service and another developer creates a client for some Amazon.com service.
The developer of the Amazon service encountered some problems so she decides to increase some timeout. The easiest way to do this to use the API you provided for the globals, so that is the one she uses.

Now when Soops decides to use both these clients in a single image we find that /unrelated/ code is affected.
In effect Cincom is providing a system that works in small projects but fails when small projects are composed into a bigger one.




The way my mind sees this problem is in terms of semiotics:
the alterations you propose /signal/ to future developers that altering the globals is the preferred way because 1) that requires the least code and 2) you imply approval by explicitly providing setters for those variables.

There are many ways to make those variables non-variable, the easiest one I described in my previous mail: default values should come from methods instead of variables. This way both 1) and 2) above are settled because there is only one way to alter the timeout (provide mySettings).
By doing it this way Soops can reliably import other clients without having to run into unexpected alterations to existing net client behavior.





Some other nitpicks: 

IMAPClient new settings timeout: 1000.


That violates encapsulation, consider
    IMAPClient new timeout: 1000

 



WsdlClient new transportClient settings timeout: 1000.


ditto: consider removing the #settings send.





(mySettings := HttpSetting new) timeout: 1000.

(Client1 := WsdlClient new) transportClient settings: mySettings.

(Client2 := WsdlClient new) transportClient settings: mySettings.


At Soops we went through various paradigms regarding settings objects, you can make a settings object 'part' of a client (as you seem to suggest above). We found that that creates all kinds of confusion: is this aspect part of some setting object or part of the state of a client?

So we moved to settings objects as factories:
  client1 := mySettings newWsdlClient.

we abandoned that pretty swiftly, it felt like it solved nothing.


Nowadays we experiment with 'simple' objects, if a client needs a timeout it will 'simply' have a variable named 'timeout'.
Settings objects are ephemeral, the client will not retain a reference to a settings object. Instead a settings object will #applyTo: a client instance.
This way settings can be composed by the re-user instead of being of fixed shape decided by the library provider.

client := Client new.
myTimoutPreferences applyTo: client.
debuggingAids applyTo: client.

etc...

If someone knows a commonly used name for this pattern I would like to hear it!




 

Is there any problem with this solution for your applications?


Many thanks for describing the plans!


Reinout
-------





 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: Reinout Heeck [[hidden email]]
Sent: Wednesday, April 11, 2012 10:34 AM
To: [hidden email]
Cc: Kogan, Tamara; Boris Popov, DeepCove Labs
Subject: Re: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

On 4/9/2012 5:35 PM, Kogan, Tamara wrote:

It makes sense.  Created for 7.10:

65132: "Change NetClient shared variables (delay/timeout/retry) to class instance variables"


This is surely a mistake, it ought to read "remove global variables".


Here at Soops we have serious problems with the various frameworks that use globals, whether for default values (as exemplified here to be allowed to vary) or for current values (eg Soap bindings). We often need to have multiple projects in a single image for purposes of refactoring, however the overuse of globals prevents us from running these projects simultaneously in a single image.

So this AR should not ask to morph class shareds into class ivars, instead it should ask to morph them into hard-coded methods (that can be overridden in subclasses).


Another way of putting this: if the contents of those shared vars is allowed to vary I can no longer use them across multiple projects. We could declare these variables as constant but (IMO) the prevailing Smalltalk idiom for that is to use methods that return a constant value instead.


My 2c.

Reinout
-------











 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: [hidden email] [[hidden email]] On Behalf Of Boris Popov, DeepCove Labs
Sent: Friday, April 06, 2012 8:18 AM
To: [hidden email]
Subject: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

What’s the point NetClient class>>defaultTimeoutValue given the below? It may be helpful to change that to a class instance variable and let subclasses define their own default timeouts.

 

NetClient class>>defaultTimeout

                ^DefaultTimeout isNil

                                ifTrue: [ DefaultTimeout := self defaultTimeoutValue ]

                                ifFalse: [ DefaultTimeout ]

 

-Boris

Sr. Software Engineer

DeepCove Labs

4th floor, 595 Howe Street

Vancouver, BC V6C 2T5

Canada

 





_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

 


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [7.8] NetClient class>>defaultTimeoutValue

Reinout Heeck-2
On 4/12/2012 5:34 PM, Steven Kelly wrote:

Thanks Reinout, I hadn’t thought of the problem of settings like that before! You’re clearly right, and I find that surprising since the solution goes against several principles I’ve found useful:

1)      where possible, it’s good to move things from being code to being data

2)      don’t embed constants in code, turn them into variables that are initialized

3)      convention over configuration

I think I’ll be a better programmer when I can find a new way to understand the deeper truths behind those principles so they aren’t in conflict with your solution! Or then maybe I agree with you on the problem, but not necessarily on the solution?


1) and 2) seem simple to me, we need to differentiate between settings and default values. These two principles seem to trivially hold for settings. When thinking about defaults to fall back to in the absence of settings however they seem to misfire. Perhaps we need to tinker with the 'where possible'  in 1).
2) seems recursive: if a setting has no value obtain an initial value from a setting?

I have a hard time understanding how to apply 3) to the current problem of supplying default values. (it makes much more sense to me in Rails-like applications where mappings are 'hard' coded using a pleasant short-hand notation/convention).

 

The first problem I see with your solution is minor: what will happen when somebody wants a different value, and doesn’t think things through: rather than adding a line to their own class to change the default value:

 

MyClass class>>initialize

   HttpSettings defaultTimeout:  1000

This would be impossible in my proposal:
- there are no global variables in use, so there is no setter on the HttpSettings class side.
- defaults are hard-coded so there are no setters for defaults, only for settings.

So it would look more like:
MyClass class>>initialize
    settingsPrototype := HttpSettings new timeout: 1000

 

they’ll do the simplest thing that can possibly work: override the hard-coded constant in the method:

 

HttpSettings class>>defaultTimeout

   ^1000 "VW used 3000, but we want less"


Depends who owns this method. If this is Cincom code it solves the original request made by Boris, if it is owned by someone else I agree it smells bad.



 

Obviously that’s not good. Instead, you suggest one approach would be subclassing:


That was the original problem: all NetClient subclasses shared a single shared variable for the default timeout while we need a system where various protocols get the ability to specify their own specialized default values.

Hmm, perhaps there's a hint how the principles you mentioned at the top break down: they don't consider the need of specialization.


 

MyHttpSettings class>>defaultTimeout

   ^1000

 

I don’t think subclassing should be used as a way of providing new values for a single setting.


Agree, I did not intend for multiple settings hierarchies. I wrote my proposals with a one-to-one relation implied between protocol classes and default providers (defaults might best be put on the NetClient hierarchy instead of a Settings hierarchy exactly to avoid this confusion).

The idea of having this as a setting is to make changing it lightweight, and adding a class is quite heavyweight. A class instance variable approach would be similar (although I don’t see why you think it’s worse).

I don't think its much wirse, merely as 'just as bad'. A single generalized global vs specialized globals is still globals.

I’d prefer to see code that instantiates an HttpClient refer to HttpClient, rather than MyHttpClient – at least until the subclass actually behave differently in something more than aspects that are considered as settings.

Exactly, I didn't intend for this interpretation.


 

I wouldn’t imagine there would be many pieces of code that would instantiate an HttpClient, so maybe the simplest practice would be to specify the timeout, where it is known the default isn’t good (of course this opens up the question of how much we trust Cincom’s defaults vs. how much we want to specify every single setting):

 

myClient := HttpClient new timeout: 1000.


Your classes might live in their own hierarchy, and thus provide opportunity for harboring their own generalization/specialization of defaults.

MyRemoteFrogulator>>initialize
   myClient := HttpClient new timeout: self defaultConnectionTimeout

 

Obviously if there are many such occurrences, all with the same settings, they can be moved to a factory method in our own class, or as an extension in HttpClient:

 

myClient := HttpClient newWithMySettings.

 

For more complex cases, your #apply’able Settings objects sound like a good solution.

 

So, the base VW would have a single, constant global value for the setting,

For the default, not the setting. And not single but specialized per-class.

and offer no mechanism for providing alternative default values within the class or its subclasses.

No: subclasses can specialize the default-providing constant method in my proposal.

The only mechanism would be instance-side, and if a team found duplication creeping into their code or the values it used, they would create their own mechanisms to avoid it. There would be convention over configuration in the base, and as teams wanted a different convention, they would implement their own so that within their own code there would be their own convention over configuration.


Could you clarify this? I don't understand what you mean by convention over configuration in this context.

 

To make the constant global value less likely to be changed or overridden, I’d suggest a Shared Variable with an initialize and constant: true. I think people wouldn’t override that as easily as they would a method.

 

This approach doesn’t break the principles I listed above, but I think it still solves the problems you identified. Thoughts?

As noted above this thread is about providing specialization opportunities for default values. When I wrote my proposal I did not have the separation of default vs setting very clear in my head.
Since that is clearer today I'd say: current values in instance variables and defaults in constant methods.
Settings are a construct/concept that can be layered on top of defaults and current values, but note that for enterprise quality I'd expect settings to live in instances not in globals.



Thanks!

Reinout
-------

 

Steve

 

From: [hidden email] [[hidden email]] On Behalf Of Reinout Heeck
Sent: 12. huhtikuuta 2012 17:16
To: [hidden email]
Subject: Re: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

On 4/11/2012 5:15 PM, Kogan, Tamara wrote:

Reinout,

 

Here is the plan for AR#65132.

 

In 7.9 we have already added NetPISettings for NetProtocolInterpreter classes and HttpSettings for HttpProtocolInterpreter.

We will add settings classes for each client PI


So far so good, this provides the mechanisms we need.



But then you say


and move delay/timeout/retry to the settings as class ivars.


which are global variables.
Moreover you treat them as variable and provide methods to make them vary:


 

To set global timeout value for HttpClient:  HttpSettings defaultTimeout:  1000.


So you signal to future generations that it is fine to alter the contents of these globals.

Consider a scenario where one developer makes a client for some Google.com service and another developer creates a client for some Amazon.com service.
The developer of the Amazon service encountered some problems so she decides to increase some timeout. The easiest way to do this to use the API you provided for the globals, so that is the one she uses.

Now when Soops decides to use both these clients in a single image we find that /unrelated/ code is affected.
In effect Cincom is providing a system that works in small projects but fails when small projects are composed into a bigger one.




The way my mind sees this problem is in terms of semiotics:
the alterations you propose /signal/ to future developers that altering the globals is the preferred way because 1) that requires the least code and 2) you imply approval by explicitly providing setters for those variables.

There are many ways to make those variables non-variable, the easiest one I described in my previous mail: default values should come from methods instead of variables. This way both 1) and 2) above are settled because there is only one way to alter the timeout (provide mySettings).
By doing it this way Soops can reliably import other clients without having to run into unexpected alterations to existing net client behavior.





Some other nitpicks: 

IMAPClient new settings timeout: 1000.


That violates encapsulation, consider
    IMAPClient new timeout: 1000

 



WsdlClient new transportClient settings timeout: 1000.


ditto: consider removing the #settings send.





(mySettings := HttpSetting new) timeout: 1000.

(Client1 := WsdlClient new) transportClient settings: mySettings.

(Client2 := WsdlClient new) transportClient settings: mySettings.


At Soops we went through various paradigms regarding settings objects, you can make a settings object 'part' of a client (as you seem to suggest above). We found that that creates all kinds of confusion: is this aspect part of some setting object or part of the state of a client?

So we moved to settings objects as factories:
  client1 := mySettings newWsdlClient.

we abandoned that pretty swiftly, it felt like it solved nothing.


Nowadays we experiment with 'simple' objects, if a client needs a timeout it will 'simply' have a variable named 'timeout'.
Settings objects are ephemeral, the client will not retain a reference to a settings object. Instead a settings object will #applyTo: a client instance.
This way settings can be composed by the re-user instead of being of fixed shape decided by the library provider.

client := Client new.
myTimoutPreferences applyTo: client.
debuggingAids applyTo: client.

etc...

If someone knows a commonly used name for this pattern I would like to hear it!




 

Is there any problem with this solution for your applications?


Many thanks for describing the plans!


Reinout
-------





 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: Reinout Heeck [[hidden email]]
Sent: Wednesday, April 11, 2012 10:34 AM
To: [hidden email]
Cc: Kogan, Tamara; Boris Popov, DeepCove Labs
Subject: Re: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

On 4/9/2012 5:35 PM, Kogan, Tamara wrote:

It makes sense.  Created for 7.10:

65132: "Change NetClient shared variables (delay/timeout/retry) to class instance variables"


This is surely a mistake, it ought to read "remove global variables".


Here at Soops we have serious problems with the various frameworks that use globals, whether for default values (as exemplified here to be allowed to vary) or for current values (eg Soap bindings). We often need to have multiple projects in a single image for purposes of refactoring, however the overuse of globals prevents us from running these projects simultaneously in a single image.

So this AR should not ask to morph class shareds into class ivars, instead it should ask to morph them into hard-coded methods (that can be overridden in subclasses).


Another way of putting this: if the contents of those shared vars is allowed to vary I can no longer use them across multiple projects. We could declare these variables as constant but (IMO) the prevailing Smalltalk idiom for that is to use methods that return a constant value instead.


My 2c.

Reinout
-------











 

Tamara Kogan

Smalltalk Development

Cincom Systems

 

From: [hidden email] [[hidden email]] On Behalf Of Boris Popov, DeepCove Labs
Sent: Friday, April 06, 2012 8:18 AM
To: [hidden email]
Subject: [vwnc] [7.8] NetClient class>>defaultTimeoutValue

 

What’s the point NetClient class>>defaultTimeoutValue given the below? It may be helpful to change that to a class instance variable and let subclasses define their own default timeouts.

 

NetClient class>>defaultTimeout

                ^DefaultTimeout isNil

                                ifTrue: [ DefaultTimeout := self defaultTimeoutValue ]

                                ifFalse: [ DefaultTimeout ]

 

-Boris

Sr. Software Engineer

DeepCove Labs

4th floor, 595 Howe Street

Vancouver, BC V6C 2T5

Canada

 





_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

 



_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: efficient, complete and fast OrderedSet

Pierre-34
In reply to this post by Pierre-34
Well no answer...
Please has anybody already created a subclass of Set that can respond to all methods of OrderedCollection??
(OrderedSet doesn't provide all the OrderedCollection methods)
Thank's in advance,
    Pierre

Le 12/04/12 11:51, Pierre Bommel a écrit :
Hy all,
I need to create and manipulate a big collection of ordered objects without duplicates.
I created a subclass of OrderedCollection for which I redefined some few methods as #addLast:
addLast: newObject
    "Add newObject to the end of the receiver.  Answer newObject."
    (self includes: newObject)
        ifFalse: [^super addLast: newObject ].
    ^newObject
This work but it's very time consuming.
I know that Set has been optimized, and I'd like to know if anybody already has created a subclass of Set that can respond to all methods of OrderedCollection??
(I don't know if OrderedSet is optimized, but it doesn't provide all the OrderedCollection methods)
Thank's for your help. All the best,

    Pierre


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: efficient, complete and fast OrderedSet

Reinout Heeck-2
On 4/28/2012 4:54 PM, Pierre Bommel wrote:
Well no answer...
Please has anybody already created a subclass of Set that can respond to all methods of OrderedCollection??
(OrderedSet doesn't provide all the OrderedCollection methods)

I love naive code, so in this case I would subclass OrderedCollection in order to guarantee the polymorphism you want.
That was step one: you have a working ordered set except that it is terribly slow.

Then I would optimize: since I love naive code I would simply add an ivar to hold on to a set and override a couple of methods to make sure that elements are stored/removed both ordered and set-ed.

From there it is a simple matter of optimizing whatever is slow in your application.


I'm sure plenty of people here have gone through these motions before, thus arriving at some ordered set implementation that is not particularly sharable with the community....


I advise to simply go for it and roll your own, a nice thing is that you can implement it incrementally over the course of your project (the TimeProfiler is your friend :-)


HTH,

Reinout
-------


Thank's in advance,
    Pierre

Le 12/04/12 11:51, Pierre Bommel a écrit :
Hy all,
I need to create and manipulate a big collection of ordered objects without duplicates.
I created a subclass of OrderedCollection for which I redefined some few methods as #addLast:
addLast: newObject
    "Add newObject to the end of the receiver.  Answer newObject."
    (self includes: newObject)
        ifFalse: [^super addLast: newObject ].
    ^newObject
This work but it's very time consuming.
I know that Set has been optimized, and I'd like to know if anybody already has created a subclass of Set that can respond to all methods of OrderedCollection??
(I don't know if OrderedSet is optimized, but it doesn't provide all the OrderedCollection methods)
Thank's for your help. All the best,

    Pierre


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: efficient, complete and fast OrderedSet

Niall Ross
In reply to this post by Pierre-34
Dear Pierre,

> Well no answer...  

Your post appeared in another thread, not its own thread, reducing the
likelihood of answers.

> Please has anybody already created a subclass of Set that can respond
> to all methods of OrderedCollection??

Reinout's approach of subclassing OrderedCollection works functionally
and is a good deal easier to write - I wrote such a class myself years
ago - but since OrderedSet appeared in the base, I've just used that
(but not much, which may explain why I've not noticed any missing
OrderedCollection methods - which are they?).

Subclassing Set would perform naturally better in some cases but worse
in others than subclassing OrderedCollection.  Dictionary is a subclass
of Set:  assign either keys or values as a sequence of numbers, it
preserves the order.  Bag is an example of using dictionary to hold
elements mapped to numbers.

> (I don't know if OrderedSet is optimized, but it doesn't provide all
> the OrderedCollection methods)

Extend OrderedSet with polymorphs of the missing OrderedCollection
methods (which are they?).

OrderedSet encapsulates an OrderedCollection and a comparison block,
thus is optimised as OrderedCollection, not as Set.  An alternative
would be to encapsulate an OrderedCollection and a Set, holding the same
objects in both.  (Cloning OrderedSet and editing its methods might be
the quickest way to create such a class.)  I've never done this
generically but have used this approach when needing both order and hash
lookup for a specific collection.

             HTH
                Niall Ross





_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc