Scala:避免可变实例变量

标签 scala playframework server-sent-events

我试图避免类中的可变实例变量,但我无法弄清楚在以下情况下如何在我的 Play 应用程序中创建用户:

当用户登录时,像 membershipList 这样的用户信息可以改变。当这样的事情改变时,应用程序使用 Play 的 Ok.feed(...) 作为服务器发送事件通知用户(上交所)。

编辑:@drstevens 指出,单播提要必须移出,因为 User 显示为 Case 类。编辑以使 User 不是案例类。

class User(id: Long, firstName: String, lastName: String, 
           membershipList: List[Group], @volatile private var signedIn = true) {
  private var infoSentOnce = false;
  private val unicastFeed: Option[Enumerator[JsValue]] = if(signedIn) Concurrent.unicast[JsValue](onStart, onComplete, onError) else None

  private def onStart(channel: Channel[JsValue]) {
    if(signedIn) {
      if(!infoSentOnce) {
        channel.push(json)
        channel.end
        infoSentOnce = true;
      }
    } else {
      channel.eofAndEnd
    }          
  }

  private def onComplete = ....

  private def onError(message: String, iteratee: Iteratee[JsValue]) = .....

  def json = {
    .....
  }

  def signedOut = signedIn = false

  def feed = unicastFeed
}

Controller 中的 Action 将是:

class MyController extends Controller with MyAuth {
  def userFeed = Authenticated { request =>   
     request.user.feed.fold(Ok(request.user.json)) { feed =>
       Ok.feed(feed 
               >& Concurrent.buffer(10)
               >& new EventSource()).as("text/event-stream"))
     }
  }
}

signedIn & infoSentOnce 是我想将其更改为不可变的两个可变变量。 infoSentOnce 可变也可能与我没有正确理解 Play 的枚举器有关。每当用户信息发生变化时,我都会创建一个新的用户对象,但我会从同一用户的先前实例复制单播枚举器。当创建新的用户实例时,Json 将被推送到用户的单播 channel 中一次。

也许在这里将 infoSentOnce 作为 var 是可以的,因为它不能被任何外部交互修改?

最佳答案

由于您的 User 类本身正在处理事件,因此它必须保持状态,这意味着它是可变的。

不可变类在外部力量完成事情时最有用,比如如果 MyController 正在登录用户,并且可以使 user = user.copy(signedOn = true)。 如果类本身正在管理状态,那么,您就需要可变性。

您可以通过用 AtomicBoolean 替换您的 bool 变量来在此处作弊以获取所有 val,但这只会将可变性移到一个级别。

关于Scala:避免可变实例变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22176822/

相关文章:

playframework - 如何在 Play 2 中进行实例级模型验证?

node.js - 服务器发送事件未使用 React 和 NodeJs 从流中接收消息

javascript - 在 HTML5 服务器发送事件中设置时间间隔

scala - 带有无形的类型转换

scala - 读取行期间的 Source.fromInputStream 异常处理

scala - 这是一个scala错误还是我做错了什么

java - Play框架-在post请求中传递多个图像

spring - Autowiring 在 Scala Spring Boot 项目中不起作用

Scala Play Framework Anorm SQL.on 禁用包装替换为 ' '

php - 服务器发送事件重复发送数据