Lift 2.5-M1 Record question

65 views
Skip to first unread message

AK

unread,
Oct 15, 2012, 5:15:24 PM10/15/12
to lif...@googlegroups.com
Hello!

I'm trying to migrate to Lift 2.5-M1 from 2.4
But my tests didn't pass after updating.

Some debugging helped to find out the reason:
Previousely at
net.liftweb.record.Field the setBox method was:

def setBox(in: Box[MyType]): Box[MyType] = synchronized {
    needsDefault = false
    data = in match {
      case _ if !canWrite_?      => Failure(noValueErrorMessage)
      case Full(_)               => set_!(in)
      case _ if optional_?       => set_!(in)
      case (f: Failure)          => set_!(f) // preserve failures set in
      case _                     => Failure(notOptionalErrorMessage)
    }
    dirty_?(true)
    data
  }

Now it became (2.5-M1):
def setBox(in: Box[MyType]): Box[MyType] = synchronized {
    needsDefault = false
    val oldValue = valueBox
    data = in match {
      case _ if !canWrite_?      => Failure(noValueErrorMessage)
      case Full(_)               => set_!(in)
      case _ if optional_?       => set_!(in)
      case (f: Failure)          => set_!(f) // preserve failures set in
      case _                     => Failure(notOptionalErrorMessage)
    }
    val same = (oldValue, valueBox) match {
      case (Full(ov), Full(nv)) => ov == nv
      case (a, b) => a == b
    }
    dirty_?(!same)
    data
  }

Here it is checked if value actually have changed, before setting to dirty. And this seems logical.

But at my code (i'm implementing Neo4jRecord) I'm overriding valueBox this way:
override def valueBox: Box[MyType] = synchronized {
    if (owner.node.isEmpty || dirty_?) super.valueBox
    else if (canRead_?) getNodeValueBox
    else getNodeValueBox.flatMap(obscure)
  }

to get the value from the record if corresponding node wasn't created yet, or if the field is dirty (changes was not yet applied to node), other way read the value from corresponding node.

Of course, I can override the setBox method at my Neo4jField, but before doing so,
I would ensure why
val same = (oldValue, valueBox)
really needs a valueBox to compare, couldn't there be just set data ?

As I see using data there instead of valueBox will bring nano-performance optimisation :)
And what is more important will isolate this change.

Should I open ticket, or just override setBox?

AK

unread,
Oct 15, 2012, 7:38:28 PM10/15/12
to lif...@googlegroups.com
Oh. Actually I cannot even override the setBox, because data and needsDefault are private for record package...

It's certainly could be replaced by
val same = (oldValue, data) match {
      case (Full(ov), Full(nv)) => ov == nv
      case (a, b) => a == b
    }

because:
def valueBox: Box[MyType] = synchronized {
//this will be just ignored as needsDefault is set to false at setBox
    if (needsDefault) {
      needsDefault = false
      data = defaultValueBox
    }

//Security check for read is not actually needed because we just checked the canWrite_? at setBox
//And even if for some reasons we can write but cannot read, it will just give us that value is not same and will set dirty_? to true
    if (canRead_?) data
    else data.flatMap(obscure)
  }


Please, I need a ticket. Just one word should be changed...



вторник, 16 октября 2012 г., 1:15:24 UTC+4 пользователь AK написал:

David Pollak

unread,
Oct 16, 2012, 12:46:51 PM10/16/12
to lif...@googlegroups.com
Please open a ticket

--
--
Lift, the simply functional web framework: http://liftweb.net
Code: http://github.com/lift
Discussion: http://groups.google.com/group/liftweb
Stuck? Help us help you: https://www.assembla.com/wiki/show/liftweb/Posting_example_code
 
 
 



--
Telegram, Simply Beautiful CMS https://telegr.am
Lift, the simply functional web framework http://liftweb.net


AK

unread,
Oct 16, 2012, 4:36:13 PM10/16/12
to lif...@googlegroups.com
Done.

https://github.com/lift/framework/issues/1335

вторник, 16 октября 2012 г., 20:46:56 UTC+4 пользователь David Pollak написал:

AK

unread,
Nov 2, 2012, 12:01:14 PM11/2/12
to lif...@googlegroups.com
I would like to add a comment.

I just find out, that even this way, it can behave not as expected.

Example:
Record has a Field with value 8 and is not dirty
we set it to 7, it becomes dirty
we again set it to 7, it becomes not dirty, but it was changed between persisting.

I believe, that before we save the record it should be kept dirty,
so the logic should be like:

dirty_?(dirty_? || { (oldValue, valueBox) match {
      case (Full(ov), Full(nv)) => ov == nv
      case (a, b) => a == b
    } })


should I add this comment to github?

среда, 17 октября 2012 г., 0:36:13 UTC+4 пользователь AK написал:

AK

unread,
Nov 2, 2012, 12:03:09 PM11/2/12
to lif...@googlegroups.com
Sorry, I ment:

dirty_?(dirty_? || { (oldValue, data) match {
      case (Full(ov), Full(nv)) => ov == nv
      case (a, b) => a == b
    } })


пятница, 2 ноября 2012 г., 20:01:14 UTC+4 пользователь AK написал:

David Whittaker

unread,
Nov 2, 2012, 2:34:59 PM11/2/12
to lif...@googlegroups.com
On Fri, Nov 2, 2012 at 12:01 PM, AK <kuprin.a...@gmail.com> wrote:
I would like to add a comment.

I just find out, that even this way, it can behave not as expected.

Example:
Record has a Field with value 8 and is not dirty
we set it to 7, it becomes dirty
we again set it to 7, it becomes not dirty, but it was changed between persisting.

I believe, that before we save the record it should be kept dirty,
so the logic should be like:

dirty_?(dirty_? || { (oldValue, valueBox) match {
      case (Full(ov), Full(nv)) => ov == nv
      case (a, b) => a == b
    } })


should I add this comment to github?

No need.  Pull request up.
Reply all
Reply to author
Forward
0 new messages