• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Knute Snortum
  • Bear Bibeault
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Tim Holloway

Locking - Notification issues

 
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi max!

I understand Derek's point Phil, but I'm not sure you understand mine: I think this because you're making an interesting, but non relevent, point .
Please review the question again, because this is integral to the lesson being taught by the SCJD.
What actual, existing, problem are you solving here?
What actual, existing, requirement are you implementing?
If you didn't go to this extra effort, what part of your assignment would you be failing?


What were the questions finally?
When I wrote (as a conclusion of some reasoning):

Data should protect his cache, period.


you replied:

This is an interesting assertion. Does a hashmap, even a synchronized one, protect it's cache, period?


As a HashMap has no "cache" (?), please concede that it was hard to understand what you meant exactly.
You next questions were:

What is the principle that leads you to believe that Data should protect it's cache? What existing problem are you solving here? And does that principle cause a conflict when applied to, say, a HashMap?


Not only both questions are open-ended but they are sort of meta-questions in fact.
To answer such questions you have no other choice but making a first guess on the real topic to be discussed...

What actual, existing, problem are you solving here?


See above, in the case a cache is implemented, which is not a requirement BTW, but the choice many people make on this forum.

What actual, existing, requirement are you implementing?


At the highest level, the main requirement in the db area is to implement the interface provided. People who implement a cache make an implementation decision, which corresponds to no requirement (even implicitly). It's OK to do it or not, but if they do it must work correctly. And I think that I demonstrated above that returning from a cache record references instead of a record copy make problem.

If you didn't go to this extra effort, what part of your assignment would you be failing?


Which extra effort?
- If you don't impelment a cache, there is no reason to fail because it's not a requirement.
- If you implement a cache which works badly, you could loose a few points if the grader points out the issue.
Regards,
Phil.
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Derek,

Felt a bit bad for starting a war , but, may i join in?


Never mind. There is no war, just an interesting discussion...
Regards,
Phil.
 
town drunk
( and author)
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Derek Canaan:
Hi Max and Phil,
Felt a bit bad for starting a war , but, may i join in?


There's no war Phil and I like to debate ideas


First, i think defensive copying, implemented or not is defendable.
In a cached-design, it's defendable because it makes the data consistent, and the Data class thread-safe. It's the same reason why we implement createRecord() in a thread-safe manner even though we are not explicitly asked to (gui only updates and searches), so that when a client invokes Data.createRecord(), we will not get data inconsistency especially for design that re-uses deleted records.
Furthermore, this gives system consistency. We have a thread-safe readRecord() and a thread-safe createRecord(). Clients are not able to mess up my data when they invoke Data.readRecord() or Data.createRecord(). My assignment states that "marks are awarded for a clear and consistent approach.
Lastly, i want to be protecetd from an assessor who may say, "Hey, i can see a security hole here. The system's locking mechanism is breached." Hence, i choose to err on the safer side.
rgds,
derek


Derek,
I see your point. This it's not a bad idea, but I'm proposing another question. Is this actually solving a problem, or is it addressing a 'what if'? That is, you're already requiring that a convention be followed(lock, modify, unlock), so what actual, real problem is being solved here?
That is, what part of the system is currently failing that you need to do this?
My goal here isn't to herd you into one solution or another, but to point out a subtle point in SE: generally, if it ain't broke, don't fix it. Now, you may feel that it is 'broke', in which case you're justifed(even obligated) to fix it. However, my opinion is that it's not, and I don't think you'd lose a single point if you didn't do it. As a matter of fact, I'm convinced you wouldn't.
All best,
M
[ February 16, 2004: Message edited by: Max Habibi ]
 
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Max,

[Max]: That is, you're already requiring that a convention be followed(lock, modify, unlock), so what actual, real problem is being solved here?

In my assignment, the lockRecord API states:

// Locks a record so that it can only be updated or deleted by this client.
// Returned value is a cookie that must be used when the record is unlocked,
// updated, or deleted. If the specified record is already locked by a different
// client, the current thread gives up the CPU and consumes no CPU cycles until
// the record is unlocked.
public long lockRecord(long recNo)
throws RecordNotFoundException;

It seems to me that the locking API only applies to update and delete. The lock/modify/unlock convention cannot apply to create because you do not have a recordNumber for lock(). So i have to make a decision on readRecord and createRecord. So i decided to make both thread-safe. I realize that in your book (great book by the way), the lock/XXX/unlock convention even applies to reads (getDVD() in DVDDbAdapter class)
But, I suppose one can put in lock(-1) to make the convention applied even for create (for consistency).
BTW, i do believe you that no points will be penalized even if i didn't do it. It's defendable too.
rgds,
derek
[ February 16, 2004: Message edited by: Derek Canaan ]
 
Max Habibi
town drunk
( and author)
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Philippe Maquet:

Hi max!
quote:
--------------------------------------------------------------------------------
I understand Derek's point Phil, but I'm not sure you understand mine: I think this because you're making an interesting, but non relevent, point .
Please review the question again, because this is integral to the lesson being taught by the SCJD.
What actual, existing, problem are you solving here?
What actual, existing, requirement are you implementing?
If you didn't go to this extra effort, what part of your assignment would you be failing?

--------------------------------------------------------------------------------
What were the questions finally?
When I wrote (as a conclusion of some reasoning):

quote:
--------------------------------------------------------------------------------
Data should protect his cache, period.
--------------------------------------------------------------------------------
you replied:


Sorry, I must have missed the reasoning . I just saw an unjustified declarative statement.


quote:
--------------------------------------------------------------------------------
This is an interesting assertion. Does a hashmap, even a synchronized one, protect it's cache, period?
--------------------------------------------------------------------------------
As a HashMap has no "cache" (?), please concede that it was hard to understand what you meant exactly.


A "cache" is simply the internal state of an object.

has a cache, and doesn't provide 'safe' access to that cache. Why is that?
When you say "Data should protect his cache, period.", I'm moved to ask why. Should all abstract data structures protect their cache from non-secured access? In that case, did the language designers at Sun make a mistake when they designed Hashmaps(for example), not to protect it's cache?
I'm not saying that doing so can't be justifed. I'm say that the assignement, IMO, doesn't motivate this sort of thing.


You next questions were:

quote:
--------------------------------------------------------------------------------
What is the principle that leads you to believe that Data should protect it's cache? What existing problem are you solving here? And does that principle cause a conflict when applied to, say, a HashMap?
--------------------------------------------------------------------------------
Not only both questions are open-ended but they are sort of meta-questions in fact.
To answer such questions you have no other choice but making a first guess on the real topic to be discussed...


In software engineering, as in all forms of engineering, there must be a guiding principle for descriptions: For example, you provide getters and setters because you're being guided the principle of encapsulation. What I'm asking you here is:
what is your guided principle for saying that "Data should protect his cache, period."



quote:
--------------------------------------------------------------------------------
What actual, existing, problem are you solving here?
--------------------------------------------------------------------------------
See above, in the case a cache is implemented, which is not a requirement BTW, but the choice many people make on this forum.
[QB]


Where above? And yes, I know a cache is the choice of many people on this forum. I was one of the first proponents of this approach, long, long ago .



quote:
--------------------------------------------------------------------------------
What actual, existing, requirement are you implementing?
--------------------------------------------------------------------------------
At the highest level, the main requirement in the db area is to implement the interface provided. People who implement a cache make an implementation decision, which corresponds to no requirement (even implicitly). It's OK to do it or not, but if they do it must work correctly. And I think that I demonstrated above that returning from a cache record references instead of a record copy make problem.
[/QB]


Yes, but I disagree with you that it forms a problem. I understand your point, but my point is that this is a potential problem: not an existing one. As is, the code will not break without this 'protection', and the requirements will have been met. As such, it's unjustified work, IMO.


quote:
--------------------------------------------------------------------------------
If you didn't go to this extra effort, what part of your assignment would you be failing?
--------------------------------------------------------------------------------
- If you implement a cache which works badly, you could loose a few points if the grader points out the issue.


I think we're disagreeing on what constitutes 'badly'. There's an old engineering joke.

Consider a glass half filled with water.
A optimist will say that the glass is half full.
A pessimist will say that the glass is half empty.
a engineer will that the glass is exactly twice as big as it needs to be.

The point is, you're not actually implementing any requirement for the SCJD here: you're doing extra work. IMO, even a little bit of that spoils the beauty of a solution what is otherwise just the perfect size. To me, this is like a artist who doesn't know when his picture is finished, and keeps 'touching it up', thus turning a work of beauty into a pretty picture.
All best,
M
 
Max Habibi
town drunk
( and author)
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Derek Canaan:
Hi Max,
quote:
--------------------------------------------------------------------------------
[Max]: That is, you're already requiring that a convention be followed(lock, modify, unlock), so what actual, real problem is being solved here?
--------------------------------------------------------------------------------
In my assignment, the lockRecord API states:
quote:
--------------------------------------------------------------------------------
// Locks a record so that it can only be updated or deleted by this client.
// Returned value is a cookie that must be used when the record is unlocked,
// updated, or deleted. If the specified record is already locked by a different
// client, the current thread gives up the CPU and consumes no CPU cycles until
// the record is unlocked.
public long lockRecord(long recNo)
throws RecordNotFoundException;
--------------------------------------------------------------------------------


Hi Derek,
This is an excellent and convincing point. In the light of the specific comment, I agree that you're not spoiling the beauty of your solution here at all.
Let me make the point I was being somewhat circumspect with.
When an object is locked, in general, it shouldn't be responsible for how it's 'inner objects' are used. For example, when you synchronize on a ArrayList, you are, in effect, 'locking down' that ArrayList.
However, you're not actually locking down the objects that the ArrayList provides access to. This isn't an accident. The general guiding principle is this: lock thyself, not thy children.
In effect, by providing the lock/unlock mechanism, you're providing a peer locking mechanism to the synchronization offered by the language. As such, it's probably a good idea to learn from the guiding principles of that mechanism. And IMO, one of the biggest of those is: you're not responsible for how people use the object you provide to them.
Now, in the case of the comment above, it's very reasonable to assume that is exactly what they wanted. OTOH, it's also very reasonable (and slightly less work) to assume it's not.


BTW, i do believe you that no points will be penalized even if i didn't do it. It's defendable too.


This is really what I wanted to clarify, and I'm glad we agree. I didn't want anyone to think that not providing this sort of mechanism is a 'badly implemented' cache, as Phil asserted.
All best,
M
[ February 16, 2004: Message edited by: Max Habibi ]
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Max,

And IMO, one of the biggest of those is: you're not responsible for how people use the object you provide to them.


Agreed, Max. As far as what they can do with the objects you provide them is consistent (and hence can be documented).
The "objects" we are talking about are the records served through the readRecord() method (which returns a String[]).
Just think of what - without Derek's solution - callers may or may not do with the returned records, depending on:
- you don't cache records at all
- you cache all records
- as I did, you support optional partial caching (where records may - by chance - be served from the file or from the cache).
Think of the fact that they may code to the DBAccess interface (even not to Data as a specific implementation) and hence have no idea whether the records they receive are safe to be modified as is or not...
"You're not responsible for how people use the object you provide to them": How could the callers be responsible for what they do with the records you provided, if they have no clue about what they can do or not?
Now BTW, do you know *any* database which returns some sort of "pointers" to its internals instead of records copies? Only *one* such database system?
Best,
Phil.
 
Max Habibi
town drunk
( and author)
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Philippe Maquet:
Hi Max,

Agreed, Max. As far as what they can do with the objects you provide them is consistent (and hence can be documented).


Phil, if you didn't document you code, I'd fail you on the spot .


Now BTW, do you know *any* database which returns some sort of "pointers" to its internals instead of records copies? Only *one* such database system?
Best,
Phil.


ever heard of EJBs?
All best,
M
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Max,

ever heard of EJBs?


A bit , and it's indeed a good example of objects which are never referenced directly, even by local clients, but it's a little out of topic I think.
Max, I must give up here. Not because I would now think that the issue pointed by Derek is not a real issue though.
I think I proved that returning direct references to cache items brings a flaw in the whole DB system (or, anyway, I cannot find better arguments than the ones already produced ).
So what to do with that information?
1. correcting the flaw with with a very few lines of code at one place in the system (where the cache serves its records)
2. keeping it and hoping the grader will not point it out.
OK, both decisions are defendable, but IMO not equally .
Best regards,
Phil.
PS: BTW, I forgot to tell you, my own cache had that flaw . Thanks again, Derek.
 
Max Habibi
town drunk
( and author)
Posts: 4118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Philippe Maquet:
Hi Max,
Max, I must give up here. Not because I would now think that the issue pointed by Derek is not a real issue though.
I think I proved that returning direct references to cache items brings a flaw in the whole DB system (or, anyway, I cannot find better arguments than the ones already produced ).


Fair enough, we'll agree to disagree. I would ask, however, that you not insist to people that is a flaw. If you choose to disregard this request, please be assured that I will take no offense.
M
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Max,

Fair enough, we'll agree to disagree.


My only issue for a few days is just finding time and energy to argue... I'll probably make a test in the next few days to check that. After all I may be wrong on the topic, even if I don't know why yet. I guess a test will make things clear.

I would ask, however, that you not insist to people that is a flaw.


Fair enough, anyway till a demonstration (if any) of the possible issue by code.

If you choose to disregard this request, please be assured that I will take no offense.


I won't!
Best,
Phil.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!