Class/Object

com.twitter.inject.thrift.modules

FilteredThriftClientModule

Related Docs: object FilteredThriftClientModule | package modules

Permalink

abstract class FilteredThriftClientModule[FutureIface <: ThriftService, ServiceIface <: Filterable[ServiceIface]] extends TwitterModule

Provides a FutureIface in the form of RemoteService[Future] for making calls to a remote service. The FutureIface (e.g., RemoteService[Future]) wraps a ServiceIface in which each method is implemented in the form of a com.twitter.finagle.Service typed from com.twitter.scrooge.ThriftMethod.Args to com.twitter.scrooge.ThriftMethod.SuccessType.

A FutureIface of RemoteService[Future] is used as this is the FutureIface type generated by Scrooge's "services-per-endpoint" functionality e.g. the result of calling Thrift.Client.newMethodIface(...); as opposed to the functionally equivalent RemoteService.FutureIface.

To provide per-method filters to the ServiceIface provide an implementation of filterServiceIface and use the provided com.twitter.inject.thrift.filters.ThriftClientFilterBuilder to filter methods. E.g.,

serviceIface.copy( fetchBlob = filters.method(FetchBlob) .withMethodLatency .withExponentialRetry( shouldRetryResponse = PossiblyRetryableExceptions, start = 50.millis, multiplier = 2, retries = 3) .withRequestLatency .withRequestTimeout(500.millis) .withConcurrencyLimit( initialPermits = 100) .filtered(new MyFilter) .filtered[MyOtherFilter] .andThen(serviceIface.fetchBlob))

Annotations
@deprecated
Deprecated

(Since version 2018-01-08) Use the com.twitter.inject.thrift.modules.ThriftMethodBuilderClientModule

See also

Finagle Clients

Services-per-endpoint in Scrooge

com.twitter.finagle.thrift.MethodIfaceBuilder

Linear Supertypes
TwitterModule, TwitterBaseModule, TwitterModuleLifecycle, Logging, util.logging.Logging, TwitterModuleFlags, AbstractModule, Module, AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. FilteredThriftClientModule
  2. TwitterModule
  3. TwitterBaseModule
  4. TwitterModuleLifecycle
  5. Logging
  6. Logging
  7. TwitterModuleFlags
  8. AbstractModule
  9. Module
  10. AnyRef
  11. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Instance Constructors

  1. new FilteredThriftClientModule()(implicit arg0: ClassTag[FutureIface], arg1: ClassTag[ServiceIface], serviceBuilder: ServiceIfaceBuilder[ServiceIface], methodBuilder: MethodIfaceBuilder[ServiceIface, FutureIface])

    Permalink

Abstract Value Members

  1. abstract val dest: String

    Permalink

    Destination of client

  2. abstract val label: String

    Permalink

    Name of client for use in metrics

Concrete Value Members

  1. final def !=(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  4. val PossiblyRetryableExceptions: PartialFunction[Try[_], Boolean]

    Permalink
    Attributes
    protected
  5. def addError(arg0: Message): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  6. def addError(arg0: Throwable): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  7. def addError(arg0: String, arg1: <repeated...>[AnyRef]): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  8. def addTypeConverter[T](converter: TypeConverter)(implicit arg0: Manifest[T]): Unit

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  9. final def asInstanceOf[T0]: T0

    Permalink
    Definition Classes
    Any
  10. def bind[T, A <: Annotation](implicit arg0: Manifest[T], arg1: Manifest[A]): ScalaAnnotatedBindingBuilder[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  11. def bind[T](annotation: Annotation)(implicit arg0: Manifest[T]): ScalaAnnotatedBindingBuilder[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  12. def bind[T](implicit arg0: Manifest[T]): ScalaAnnotatedBindingBuilder[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  13. def bind[T](arg0: Class[T]): AnnotatedBindingBuilder[T]

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  14. def bind[T](arg0: TypeLiteral[T]): AnnotatedBindingBuilder[T]

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  15. def bind[T](arg0: Key[T]): LinkedBindingBuilder[T]

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  16. def bindAssistedFactory[T]()(implicit arg0: Manifest[T]): Unit

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  17. def bindConstant(): AnnotatedConstantBindingBuilder

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  18. def bindInterceptor(arg0: Matcher[_ >: Class[_]], arg1: Matcher[_ >: Method], arg2: <repeated...>[MethodInterceptor]): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  19. def bindListener(arg0: Matcher[_ >: Binding[_]], arg1: <repeated...>[ProvisionListener]): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  20. def bindListener(arg0: Matcher[_ >: TypeLiteral[_]], arg1: TypeListener): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  21. def bindScope(arg0: Class[_ <: Annotation], arg1: Scope): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  22. def bindSingleton[T, A <: Annotation](implicit arg0: Manifest[T], arg1: Manifest[A]): ScalaAnnotatedBindingBuilder[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  23. def bindSingleton[T](annotation: Annotation)(implicit arg0: Manifest[T]): ScalaAnnotatedBindingBuilder[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  24. def bindSingleton[T](implicit arg0: Manifest[T]): ScalaAnnotatedBindingBuilder[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  25. def binder(): Binder

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  26. def budget: Budget

    Permalink

    Default com.twitter.finagle.service.RetryBudget.

    Default com.twitter.finagle.service.RetryBudget. It is highly recommended that budgets be shared between all filters that retry or re-queue requests to prevent retry storms.

    returns

    a default com.twitter.finagle.service.RetryBudget

    Attributes
    protected
    See also

    https://twitter.github.io/finagle/guide/Clients.html#retries

  27. def clone(): AnyRef

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  28. def closeOnExit(f: ⇒ Unit): Unit

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModuleLifecycle
  29. def configure(): Unit

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule → AbstractModule
  30. final def configure(arg0: Binder): Unit

    Permalink
    Definition Classes
    AbstractModule → Module
  31. def configureNonThriftMuxClient(client: Client): Client

    Permalink

    This method allows for further configuration of the client for parameters not exposed by this module or for overriding defaults provided herein, e.g.,

    This method allows for further configuration of the client for parameters not exposed by this module or for overriding defaults provided herein, e.g.,

    override def configureNonThriftMuxClient(client: Thrift.Client): Thrift.Client = { client .withProtocolFactory(myCustomProtocolFactory)) .withStatsReceiver(someOtherScopedStatsReceiver) .withMonitor(myAwesomeMonitor) .withTracer(notTheDefaultTracer) .withResponseClassifier(ThriftResponseClassifier.ThriftExceptionsAsFailures) }

    In general it is recommended that users prefer to use ThriftMux if the server-side supports mux connections.

    client

    - the com.twitter.finagle.Thrift.Client to configure.

    returns

    a configured Thrift.Client.

    Attributes
    protected
  32. def configureThriftMuxClient(client: Client): Client

    Permalink

    This method allows for further configuration of the client for parameters not exposed by this module or for overriding defaults provided herein, e.g.,

    This method allows for further configuration of the client for parameters not exposed by this module or for overriding defaults provided herein, e.g.,

    override def configureThriftMuxClient(client: ThriftMux.Client): ThriftMux.Client = { client .withProtocolFactory(myCustomProtocolFactory)) .withStatsReceiver(someOtherScopedStatsReceiver) .withMonitor(myAwesomeMonitor) .withTracer(notTheDefaultTracer) .withResponseClassifier(ThriftResponseClassifier.ThriftExceptionsAsFailures) }

    client

    - the com.twitter.finagle.ThriftMux.Client to configure.

    returns

    a configured ThriftMux.Client.

    Attributes
    protected
  33. def convertToTypes(arg0: Matcher[_ >: TypeLiteral[_]], arg1: TypeConverter): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  34. def createFlag[T](name: String, default: T, help: String, flaggable: Flaggable[T]): Flag[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModuleFlags
  35. def createKey[T](implicit arg0: Manifest[T]): Key[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterBaseModule
  36. def createMandatoryFlag[T](name: String, help: String, usage: String, flaggable: Flaggable[T]): Flag[T]

    Permalink
    Definition Classes
    TwitterModuleFlags
  37. def createMultiBinder[MultiBindType](implicit arg0: Manifest[MultiBindType]): ScalaMultibinder[MultiBindType]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  38. def currentStage(): Stage

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  39. def debug(marker: Marker, message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  40. def debug(message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  41. def debug(marker: Marker, message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  42. def debug(message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  43. def debugFutureResult[T](msg: String)(func: ⇒ Future[T]): Future[T]

    Permalink
    Attributes
    protected
    Definition Classes
    Logging
  44. def debugResult[T](message: ⇒ String)(fn: ⇒ T): T

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  45. final def eq(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  46. def equals(arg0: Any): Boolean

    Permalink
    Definition Classes
    AnyRef → Any
  47. def error(marker: Marker, message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  48. def error(message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  49. def error(marker: Marker, message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  50. def error(message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  51. def errorResult[T](message: ⇒ String)(fn: ⇒ T): T

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  52. def filterServiceIface(serviceIface: ServiceIface, filters: ThriftClientFilterBuilder): ServiceIface

    Permalink

    Add filters to the ServiceIface.

    Add filters to the ServiceIface. This is done by copying the ServiceIface then filtering each method as desired via a com.twitter.inject.thrift.filters.ThriftClientFilterChain returned from com.twitter.inject.thrift.filters.ThriftClientFilterBuilder.method. E.g.,

    filters.method(FetchBlob) .withMethodLatency .withConstantRetry( shouldRetryResponse = PossiblyRetryableExceptions, start = 50.millis, retries = 3) .withRequestLatency .withRequestTimeout(250.millis) .withConcurrencyLimit( initialPermits = 500) .filtered(new MyFilter) .filtered[MyOtherFilter] .andThen(serviceIface.fetchBlob))

    Note: the com.twitter.inject.thrift.filters.ThriftClientFilterChain supports adding filters either by instance or by type.

    Subclasses of this module MAY provide an implementation of filterServiceIface which filters the ServiceIface per-method.

    serviceIface

    - the ServiceIface to filter per-method.

    filters

    - a com.twitter.inject.thrift.filters.ThriftClientFilterBuilder which can be invoked to construct a com.twitter.inject.thrift.filters.ThriftClientFilterChain per-method.

    returns

    a per-method filtered ServiceIface

    Attributes
    protected
    See also

    com.twitter.inject.thrift.filters.ThriftClientFilterChain

  53. def finalize(): Unit

    Permalink
    Attributes
    protected[java.lang]
    Definition Classes
    AnyRef
    Annotations
    @throws( classOf[java.lang.Throwable] )
  54. def flag[T](name: String, help: String)(implicit arg0: Flaggable[T], arg1: Manifest[T]): Flag[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModuleFlags
  55. def flag[T](name: String, default: T, help: String)(implicit arg0: Flaggable[T]): Flag[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModuleFlags
  56. val flags: ArrayBuffer[Flag[_]]

    Permalink
    Attributes
    protected[com.twitter.inject]
    Definition Classes
    TwitterModuleFlags
  57. val frameworkModules: Seq[TwitterModule]

    Permalink
    Definition Classes
    FilteredThriftClientModule → TwitterBaseModule
  58. final def getClass(): Class[_]

    Permalink
    Definition Classes
    AnyRef → Any
  59. def getMembersInjector[T](arg0: TypeLiteral[T]): MembersInjector[T]

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  60. def getMembersInjector[T](arg0: Class[T]): MembersInjector[T]

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  61. def getProvider[T](implicit arg0: Manifest[T]): Provider[T]

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule
  62. def getProvider[T](arg0: Class[T]): Provider[T]

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  63. def getProvider[T](arg0: Key[T]): Provider[T]

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  64. def hashCode(): Int

    Permalink
    Definition Classes
    AnyRef → Any
  65. def info(marker: Marker, message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  66. def info(message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  67. def info(marker: Marker, message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  68. def info(message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  69. def infoResult[T](message: ⇒ String)(fn: ⇒ T): T

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  70. def install(module: Module): Unit

    Permalink
    Attributes
    protected
    Definition Classes
    TwitterModule → AbstractModule
  71. def isDebugEnabled(marker: Marker): Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  72. def isDebugEnabled: Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  73. def isErrorEnabled(marker: Marker): Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  74. def isErrorEnabled: Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  75. def isInfoEnabled(marker: Marker): Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  76. def isInfoEnabled: Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  77. final def isInstanceOf[T0]: Boolean

    Permalink
    Definition Classes
    Any
  78. def isTraceEnabled(marker: Marker): Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  79. def isTraceEnabled: Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  80. def isWarnEnabled(marker: Marker): Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  81. def isWarnEnabled: Boolean

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  82. final def logger: Logger

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  83. final def loggerName: String

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  84. def modules: Seq[Module]

    Permalink
    Attributes
    protected[com.twitter.inject]
    Definition Classes
    TwitterBaseModule
  85. def monitor: Monitor

    Permalink

    Function to add a user-defined Monitor, c.t.finagle.DefaultMonitor will be installed implicitly which handles all exceptions caught in stack.

    Function to add a user-defined Monitor, c.t.finagle.DefaultMonitor will be installed implicitly which handles all exceptions caught in stack. Exceptions aren't handled by user-defined monitor propagated to the default monitor.

    NullMonitor has no influence on DefaultMonitor behavior here

    Attributes
    protected
  86. val mux: Boolean

    Permalink

    Enable thrift mux for this connection.

    Enable thrift mux for this connection.

    Note: Both server and client must have mux enabled otherwise a nondescript ChannelClosedException will be seen.

    Attributes
    protected
    See also

    What is ThriftMux?

  87. final def ne(arg0: AnyRef): Boolean

    Permalink
    Definition Classes
    AnyRef
  88. final def notify(): Unit

    Permalink
    Definition Classes
    AnyRef
  89. final def notifyAll(): Unit

    Permalink
    Definition Classes
    AnyRef
  90. final def providesClient(timeoutMultiplier: Int, retryMultiplier: Int, serviceIface: ServiceIface, injector: Injector, statsReceiver: StatsReceiver, andThenService: AndThenService): FutureIface

    Permalink
    Annotations
    @Provides() @Singleton()
  91. final def providesUnfilteredServiceIface(timeoutMultiplier: Int, clientId: ClientId, statsReceiver: StatsReceiver): ServiceIface

    Permalink
    Annotations
    @Provides() @NonFiltered() @Singleton()
  92. def requestInjection(arg0: Any): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  93. def requestStaticInjection(arg0: <repeated...>[Class[_]]): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  94. def requireBinding(arg0: Class[_]): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  95. def requireBinding(arg0: Key[_]): Unit

    Permalink
    Attributes
    protected[com.google.inject]
    Definition Classes
    AbstractModule
  96. def sessionAcquisitionTimeout: Duration

    Permalink

    Configures the session acquisition timeout of this client (default: unbounded).

    Configures the session acquisition timeout of this client (default: unbounded).

    returns

    an com.twitter.util.Duration which represents the acquisition timeout

    Attributes
    protected
    See also

    https://twitter.github.io/finagle/guide/Clients.html#timeouts-expiration

    com.twitter.finagle.param.ClientSessionParams#acquisitionTimeout

  97. def singletonPostWarmupComplete(injector: Injector): Unit

    Permalink
    Attributes
    protected[com.twitter.inject]
    Definition Classes
    TwitterModuleLifecycle
  98. def singletonShutdown(injector: Injector): Unit

    Permalink
    Attributes
    protected[com.twitter.inject]
    Definition Classes
    TwitterModuleLifecycle
  99. def singletonStartup(injector: Injector): Unit

    Permalink
    Attributes
    protected[com.twitter.inject]
    Definition Classes
    TwitterModuleLifecycle
  100. final def synchronized[T0](arg0: ⇒ T0): T0

    Permalink
    Definition Classes
    AnyRef
  101. def time[T](formatStr: String)(func: ⇒ T): T

    Permalink
    Attributes
    protected
    Definition Classes
    Logging
  102. def toString(): String

    Permalink
    Definition Classes
    AnyRef → Any
  103. def trace(marker: Marker, message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  104. def trace(message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  105. def trace(marker: Marker, message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  106. def trace(message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  107. def traceResult[T](message: ⇒ String)(fn: ⇒ T): T

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  108. val useHighResTimerForRetries: Boolean

    Permalink

    Use a high resolution com.twitter.util.Timer such that retries are run tighter to their schedule.

    Use a high resolution com.twitter.util.Timer such that retries are run tighter to their schedule. Default: false.

    Note: There are performance implications to enabling.

    Attributes
    protected
  109. final def wait(): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  110. final def wait(arg0: Long, arg1: Int): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  111. final def wait(arg0: Long): Unit

    Permalink
    Definition Classes
    AnyRef
    Annotations
    @throws( ... )
  112. def warn(marker: Marker, message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  113. def warn(message: ⇒ Any, cause: Throwable): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  114. def warn(marker: Marker, message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  115. def warn(message: ⇒ Any): Unit

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging
  116. def warnResult[T](message: ⇒ String)(fn: ⇒ T): T

    Permalink
    Attributes
    protected[this]
    Definition Classes
    Logging

Inherited from TwitterModule

Inherited from TwitterBaseModule

Inherited from TwitterModuleLifecycle

Inherited from Logging

Inherited from util.logging.Logging

Inherited from TwitterModuleFlags

Inherited from AbstractModule

Inherited from Module

Inherited from AnyRef

Inherited from Any

Ungrouped