Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate extension via Doctrine Event Manager #5784

Closed
morozov opened this issue Oct 21, 2022 · 21 comments · Fixed by #5786
Closed

Deprecate extension via Doctrine Event Manager #5784

morozov opened this issue Oct 21, 2022 · 21 comments · Fixed by #5786

Comments

@morozov
Copy link
Member

morozov commented Oct 21, 2022

Recently, I tried to enable checking exceptions in PHPStan and, besides a few other issues with the DBAL API, stumbled upon the one that shows what an awfully overcomplicated piece of work the Events API is:

  1. AbstractPlatform::getDropTableSQL() dispatches an onSchemaDropTable event which can override the SQL used to drop the table.
  2. The return type of SchemaDropTableEventArgs::getSql() is ?string. If it returns NULL, the platform will throw an UnexpectedValueException.
  3. There's no way to tell that a given method is an event handler unless it's documented as such or whoever reads the code knows that the methods with names starting with on are event handlers. Those methods are not invoked from anywhere in the code explicitly.

Here's a chain of questions that leads to the above conclusion:

  1. Why is SchemaDropTableEventArgs allowed to return NULL if it's not even a valid value?
  2. We could require that it returns a string but then what would it return if the handler of the event didn't call setSql()?
  3. Putting aside the event-handling scenario, what should the SchemaDropTableEventArgs class do if it was instantiated and then got its setSql() invoked? Maybe throw a logical exception?
  4. Then, should it throw this exception unconditionally or only if it got a call to preventDefault() first?

Problems with the API design and implementation

What this API does, most likely could be solved just by extending the platform class and overriding the corresponding methods. Besides this awfully implicitly stateful logic, a few more concerns about DDL events:

  1. It looks like it's an overengineered solution to what could be easily solved by extending the corresponding platform methods.
  2. Unlike extending the platform, events don't allow invoking the default implementation (the method of the parent class).
  3. Unlike class extension, events don't provide access to the original logic like a call to the parent method would.
  4. The DDL events API is incomplete (e.g. one can override DROP TABLE but cannot override DROP FOREIGN KEY).
  5. In event-driven systems and DDD, an event is an immutable object representing a fact that happened in the past. Which fact does an onSchemaDropTable event represent? Let's assume it's a fact that somebody intended to drop a table. Why is it mutable? Why does it carry any information about processing the event (prevent default) and even implementation of that processing (SQL)?
  6. For 800 lines of production code, there are three unit tests with mocks and not a single integration test which would demonstrate how this API can be used and if it can be used at all.
  7. The documentation shows only how to register handlers but not what they should to.

Problems with the EventManager API as such

This API is unsafe from the standpoint of the types:

  1. There's no way to enforce the fact that a given event (onSomething) is dispatched only with a specific type of arguments (SomethingArgs).
  2. There's no way to guarantee that the given listener supports handling the given type of event. The dispatcher calls the method corresponding to the event name dynamically:
    $listener->$eventName($eventArgs)

The mistakes in the code that implements the handling of events will lead to a type error at runtime.

Types of events

  1. Connection and transaction events:
    public const postConnect = 'postConnect';

    dbal/src/Events.php

    Lines 33 to 35 in a85d913

    public const onTransactionBegin = 'onTransactionBegin';
    public const onTransactionCommit = 'onTransactionCommit';
    public const onTransactionRollBack = 'onTransactionRollBack';
    The logic implemented on top of these events can be implemented using driver middlewares.
  2. Schema manipulation events:

    dbal/src/Events.php

    Lines 23 to 30 in a85d913

    public const onSchemaCreateTable = 'onSchemaCreateTable';
    public const onSchemaCreateTableColumn = 'onSchemaCreateTableColumn';
    public const onSchemaDropTable = 'onSchemaDropTable';
    public const onSchemaAlterTable = 'onSchemaAlterTable';
    public const onSchemaAlterTableAddColumn = 'onSchemaAlterTableAddColumn';
    public const onSchemaAlterTableRemoveColumn = 'onSchemaAlterTableRemoveColumn';
    public const onSchemaAlterTableChangeColumn = 'onSchemaAlterTableChangeColumn';
    public const onSchemaAlterTableRenameColumn = 'onSchemaAlterTableRenameColumn';
    Depending on the use case, it should be advised to either extend the corresponding platform method, or modify the arguments being passed to the method before calling it.
  3. Schema introspection events:

    dbal/src/Events.php

    Lines 31 to 32 in a85d913

    public const onSchemaColumnDefinition = 'onSchemaColumnDefinition';
    public const onSchemaIndexDefinition = 'onSchemaIndexDefinition';
    This is the hardest part: we allow users to hook into the very internals of the schema introspection, e.g. the API consumer is exposed to the SQL results representing raw introspected data. By definition, this API is very brittle since the raw results is an implementation detail that can and will change. The fact that we allow this extension complicates the refactoring of the Schema Manager and Platform API.
@morozov morozov added this to the 3.5.0 milestone Oct 22, 2022
@morozov morozov linked a pull request Oct 22, 2022 that will close this issue
@morozov morozov changed the title Deprecate extension via events Deprecate extension via Doctrine Event Manager Oct 22, 2022
@morozov morozov closed this as completed Oct 22, 2022
@flack
Copy link
Contributor

flack commented Oct 28, 2022

I don't want to sound too negative, but that's a bit of a drive-by deprecation, no? Ticket was opened 7 days ago and 6 days ago it was merged. Would be nice to have a bit of a heads-up on stuff that requires consumers to rewrite their stuff.

I am currently using the onSchemaColumnDefinition and onSchemaCreateTable, did I understand it correctly that now instead of using these events, I'm supposed to extend/override all the Platform classes I use?

@greg0ire
Copy link
Member

Would be nice to have a bit of a heads-up on stuff that requires consumers to rewrite their stuff.

Isn't that exactly what a deprecation does? What would you do?

did I understand it correctly that now instead of using these events, I'm supposed to extend/override all the Platform classes I use?

I don't think that's the right thing to do, see https://doctrine.slack.com/archives/CA9600CLC/p1666886106048959

@flack
Copy link
Contributor

flack commented Oct 28, 2022

Isn't that exactly what a deprecation does? What would you do?

I just mean the plan to deprecate was announced (i.e. this ticket opened) and one day later it was already implemented. It just seems like it would have been nicer to keep it open for a while to see if there is any user feedback (Also, some migration guide would really be appreciated).

I don't think that's the right thing to do, see https://doctrine.slack.com/archives/CA9600CLC/p1666886106048959

That wants me to log into something. Is there a public version of it maybe?

@derrabus
Copy link
Member

The deprecation of the event system happened in an effort to consolidate our extension points. But if we discover that this deprecation was premature, we can talk about it. Can you please open a new issue where you explain for what purpose you use the event system and why extending the platform would make that more difficult for you?

@flack
Copy link
Contributor

flack commented Oct 28, 2022

Sure, I can look into that. To be clear: I don't mind you deprecating stuff as long as there's an alternative way to implement the functionality I need.

Just to make sure: @derrabus you think extending Platform (as in Doctrine\DBAL\Platforms\SqlitePlatform etc.?) would the the way to go, but @greg0ire you don't think so?

BTW, one scenario I use I described here:

#4676 (comment)

@greg0ire
Copy link
Member

@flack
Copy link
Contributor

flack commented Oct 28, 2022

@greg0ire thanks for the info! I just tried to figure this out, but somehow I'm stuck: AFAICT the SchemaManager to use gets determined in the Platform:

public function createSchemaManager(Connection $connection): SqliteSchemaManager
{
return new SqliteSchemaManager($connection, $this);
}

So to use a custom SchemaManager I would have to extend the Platform to return my own instance. The Platform gets determined in the Driver:

public function getDatabasePlatform()
{
return new SqlitePlatform();
}

And to override the Driver, I would have to use driverClass here:

dbal/src/DriverManager.php

Lines 245 to 253 in d3b8e80

if (isset($params['driverClass'])) {
$interfaces = class_implements($params['driverClass']);
if ($interfaces === false || ! in_array(Driver::class, $interfaces, true)) {
throw Exception::invalidDriverClass($params['driverClass']);
}
return new $params['driverClass']();
}

Which means I'd have to copy the self::DRIVER_MAP logic (because it's private), but then also the actual driver class is marked final, so I can't extend it:

final class Driver extends AbstractSQLiteDriver

Is there something I'm missing?

@derrabus
Copy link
Member

The Platform gets determined in the Driver

… if you don't pass one via the platform option to the DriverManager.

@flack
Copy link
Contributor

flack commented Oct 31, 2022

@derrabus thanks, that helped! So for onSchemaColumnDefinition, I would need approximately this amount of boilerplate, right?

$db_config = [/* config as before, driver set to pdo_mysql or pdo_sqlite */];

if ($db_config['driver'] == 'pdo_mysql') {
    $db_config['platform'] = my_mysql_platform::class;
} elseif ($db_config['driver'] == 'pdo_sqlite') {
    $db_config['platform'] = my_sqlite_platform::class;
} else {
    throw new Exception('Oh noes!!!');
}
/* startup connection as before */

class my_mysql_platform extends Doctrine\DBAL\Platforms\MySQLPlatform
{
    public function createSchemaManager(Doctrine\DBAL\Connection $connection): Doctrine\DBAL\Schema\MySQLSchemaManager
    {
        return new my_mysql_schemamanager($connection, $this);
    }
}

class my_sqlite_platform extends Doctrine\DBAL\Platforms\SqlitePlatform
{
    public function createSchemaManager(Doctrine\DBAL\Connection $connection): Doctrine\DBAL\Schema\SqliteSchemaManager
    {
        return new my_sqlite_schemamanager($connection, $this);
    }
}

class my_mysql_schemamanager extends Doctrine\DBAL\Schema\MySQLSchemaManager
{
    protected function _getPortableTableColumnList($table, $database, $tableColumns)
    {
        $tableColumns = onSchemaColumnDefinition($tableColumns);
        return parent::_getPortableTableColumnList($table, $database, $tableColumns);
    }
}

class my_sqlite_schemamanager extends Doctrine\DBAL\Schema\SqliteSchemaManager
{
    protected function _getPortableTableColumnList($table, $database, $tableColumns)
    {
        $tableColumns = onSchemaColumnDefinition($tableColumns);
        return parent::_getPortableTableColumnList($table, $database, $tableColumns);
    }
}

function onSchemaColumnDefinition($tableColumns)
{
    /* event listener code goes here */
    return $tableColumns;
}

Not exactly pretty, but I guess somewhat manageable, if those protected functions stay stable at least. The onSchemaCreateTable looks a bit more annoying to simulate though, because it's kind of called in the middle of a function, and it doesn't look like there's a way to just inject something without copying half the method's code (although, in fairness, my current listener also copies most of the _getCreateTableSQL function due to the way preventDefault works)

@derrabus
Copy link
Member

Yes, that looks about right.

@jaroslavlibal
Copy link

jaroslavlibal commented Oct 31, 2022

Hello, I am the author of the Slack question mentioned above. Thank you for your discussion and suggestions. I am trying to implement the solution proposed by @flack , but I am running into the fact that I will probably have to extend the Driver as well.

The reason is that although I pass the platform in the connection configuration, the original SchemaManager is created in the Driver's getSchemaManager() method and my createSchemaManager() method is never called.

This brings me back to the fact that Doctrine\DBAL\Driver\PDO\PgSQL\Driver is final.

Did I understand that correctly, please? Thanks!

@Brajk19
Copy link

Brajk19 commented Nov 3, 2022

@jaroslavlibal
you can use decorator to wrap Driver and make doctrine use your custom schema manager

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Driver\API\ExceptionConverter;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;

class YourCustomDriver implements Driver
{
    public function __construct(
        private readonly Driver $underlyingDriver
    ) {
    }

    public function getSchemaManager(Connection $conn, AbstractPlatform $platform)
    {
        return $platform->createSchemaManager($conn);
    }

    public function connect(array $params): Driver\Connection
    {
        return $this->underlyingDriver->connect($params);
    }

    public function getDatabasePlatform(): AbstractPlatform
    {
        return $this->underlyingDriver->getDatabasePlatform();
    }

    public function getExceptionConverter(): ExceptionConverter
    {
        return $this->underlyingDriver->getExceptionConverter();
    }
}
use Doctrine\DBAL\Driver;
class Middleware implements Driver\Middleware
{
    public function wrap(Driver $driver): Driver
    {
        return new YourCustomDriver($driver);
    }
}

if you configured everything else correctly this code will make sure your custom schema manager is used

in my case, i've extended PostgreSQLPlatform and overriden createSchemaManager to return custom schema manager
you'll also need to edit your doctrine.yaml config with custom platform:

doctrine:
  dbal:
    platform_service: <yourCustomPlatform>

@alekitto
Copy link
Contributor

alekitto commented Nov 4, 2022

The effort and goal is clear, the way this has been done unfortunately is very rough.

API is inconsistent and could be done better: ok, we can agree on that. But deprecate an extension system in full without a single day of discussion is unpleasant, especially if done in a such popular project like this one.

On technical aspects:

  • some events can be replaced by middlewares: upgrade path here is clear and sound, but they are only two. Most of those cannot be replaced this way.
  • generated/custom sql is not the only information carried by the event object: tables and columns for example can be retrieved and modified in the event handler.
  • you suggested to extend the platform, but it is obviously too overkill when the only thing you have to do is to add a column to a table. On the contrary, when you need to modify various tables it is simpler and more maintenable to have such code in different classes you could unit-test separately.
  • you also suggested to modify the input before using schema manager/platform, but this is not always feasible, especially when using the ORM.
  • DDD is not the goal of this library, immutability is not required for the events. Events here are an extension point, not something to be saved/retained as part of the normal flow.
  • dynamic method call is unreliable and api of the event manager can be fragile. Ok, but meanwhile some community standards have been published and widely used. Using a PSR-compatible event dispatcher can help to clean up the code and can help you to move the maintenance burden of the event manager to others.

IMHO the way this thing has been done is not very nice to the community, and lacked a wider vision on how this project is used in the wild. What makes me sad is the low consideration of the community feedback: 24 hours issue is barely a communication and left no space for discussion. To me this is not acceptable in a such important project: it is widely used, production apps are written onto it and should take this responsibility seriously giving the community the time to evaluate such an important change and express an opinion.

@derrabus
Copy link
Member

derrabus commented Nov 6, 2022

But deprecate an extension system in full without a single day of discussion is unpleasant, especially if done in a such popular project like this one.

I don't know if you realize that or if you just haven't read the previous comments, but we're actually having the discussion you're asking for. A deprecation is not an immediate removal. And we we can surely take it back if you give us good reasons to.

generated/custom sql is not the only information carried by the event object: tables and columns for example can be retrieved and modified in the event handler.

Do you think, an event handler is the best way to expose this kind of extension point? If you designed this feature from scratch, how would you build the extension point that you need for your scenario?

you suggested to extend the platform, but it is obviously too overkill when the only thing you have to do is to add a column to a table.

Why would you need to hook into the DBAL to add a column? Why can't you add it to the schema directly? Sorry if my question sounds stupid, but I'd like to understand you problem before we decide on an action here.

you also suggested to modify the input before using schema manager/platform, but this is not always feasible, especially when using the ORM.

Can you give us examples? Is this something the ORM should address instead?

Using a PSR-compatible event dispatcher can help to clean up the code and can help you to move the maintenance burden of the event manager to others.

The event manager is a trivial library. Sunsetting it is not our intention and certainly was not the motivation here.

@alekitto
Copy link
Contributor

alekitto commented Nov 6, 2022

I don't know if you realize that or if you just haven't read the previous comments, but we're actually having the discussion you're asking for. A deprecation is not an immediate removal. And we we can surely take it back if you give us good reasons to.

From my POV, a discussion is needed before to take action, not after. This is a communication of what's have been already done, and doesn't matter if it can be un-done. A discussion can take place on a proposal, which this is not. This is a fact: events have been deprecated in the current public release and removed in the first beta of the next major version.

Do you think, an event handler is the best way to expose this kind of extension point? If you designed this feature from scratch, how would you build the extension point that you need for your scenario?

Yes, why not? An entire framework (Symfony) has been written around an event manager, where handlers continuously modify and process information and structures, for example enhancing the request object, transforming the request body, etc.
Why DBAL cannot use the same flow?
To be clear: I don't mean that everything in the current event system is ok and does not need to be revisited/reworked, but surely I would retain the event system as a powerful extension point.

Why would you need to hook into the DBAL to add a column? Why can't you add it to the schema directly? Sorry if my question sounds stupid, but I'd like to understand you problem before we decide on an action here.
Can you give us examples? Is this something the ORM should address instead?

I'll answer two questions here because they are connected. I'll give you some examples:

  • I have an ORM entity with a "priority" field but I want to avoid that two records have the same exact value, so when you set a value that already exists, all the values after it needs to be updated. The ORM can handle it, but its very costly, so I made an optimization with a trigger that involves an additional column on that table. At the same time I want that column to be hidden from the ORM, it does not really exist, it's an implementation detail. Using the migrations library I cannot modify the schema in the middle of the process, I have to hook into DBAL and add the column when necessary.
  • I wrote a Symfony Messenger transport that uses DBAL as storage backend. I want its tables and resources to be completely hidden from the ORM. In the bundle I have to register an event handler to generate the resources on schema creation so the doctrine's commands will work with no additional configuration.
  • I have an application that uses a table with the "ARCHIVE" mysql engine. Using the ORM I cannot set it correctly, I have to hook into the schema generation process and modify the engine from "InnoDB" to "ARCHIVE".
  • In an application I want to generate a VIEW resource alongside a normal table: this is something that cannot be done into the ORM. To work with schema commands and migrations I have to hook into DBAL in the middle of the schema generation.
  • For a translation system I have to dynamically generate translation tables to be used as storage for the various "translatable" resources: again this is something that needs to be hidden from the ORM, but needs to work with schema commands and migrations.

The event manager is a trivial library. Sunsetting it is not our intention and certainly was not the motivation here.

So those listed under "Problems with the EventManager API as such" are not valid reasons to deprecate and remove the event system? Because a PSR-compatible event dispatcher will solve both problems. And lately, will increase the integration level with the frameworks in general.

@derrabus
Copy link
Member

derrabus commented Nov 6, 2022

From my POV, a discussion is needed before to take action, not after.

And you would've participated in that discussion? Would you have noticed that it even happens? During the last months of DBAL development, I have barely seen any real discussion going on any PR. Users of the DBAL don't monitor this repository and that's absolutely okay. Trust me: We could've kept that PR open for two more weeks and the only difference would've been that you would have one thing less to complain about.

Really, I value every constructive feedback that we get from the community. But please think about how you address people who invest their free-time to build libraries that you can use for free. A phrase like "this is not acceptable" feels a bit inappropriate here, don't you think?

Using the migrations library I cannot modify the schema in the middle of the process, I have to hook into DBAL and add the column when necessary.

I think, this is the issue we have to solve. We need to enable you to modify the schema after the ORM has generted it from the metadata and before it's being used for comparisons with the actual database.

I have an application that uses a table with the "ARCHIVE" mysql engine. Using the ORM I cannot set it correctly, I have to hook into the schema generation process and modify the engine from "InnoDB" to "ARCHIVE".

Do you think, we should enable you configure vendor-specific tweaks like that in the ORM?

In an application I want to generate a VIEW resource alongside a normal table: this is something that cannot be done into the ORM. To work with schema commands and migrations I have to hook into DBAL in the middle of the schema generation.

For a translation system I have to dynamically generate translation tables to be used as storage for the various "translatable" resources: again this is something that needs to be hidden from the ORM, but needs to work with schema commands and migrations.

You should be abler to configure patterns of table names that should be ignored during schema comparisons, shouldn't you? I have to look that up though, not entirely sure about how to configure that.

The event manager is a trivial library. Sunsetting it is not our intention and certainly was not the motivation here.

So those listed under "Problems with the EventManager API as such" are not valid reasons to deprecate and remove the event system? Because a PSR-compatible event dispatcher will solve both problems.

No, if those were our only problems with the event system, we wouldn't have deprecated it. You are right, a PSR-4 dispatcher would be the solution here.

And lately, will increase the integration level with the frameworks in general.

I agree. If you want to work on switching the ORM to PSR-14, don't hesitate to investigate a possible migration path.

@alekitto
Copy link
Contributor

alekitto commented Nov 6, 2022

And you would've participated in that discussion? Would you have noticed that it even happens?
Really, I value every constructive feedback that we get from the community. But please think about how you address people who invest their free-time to build libraries that you can use for free. A phrase like "this is not acceptable" feels a bit inappropriate here, don't you think?

Really, I don't want to open a flame, so just two things on these and then I want to discuss only the technical aspects: presuming that the discussion would pass unnoticed is wrong in my opinion, and no, to me is not inappropriate because is my point-of-view.
On the "it's free/my free time and work" that is used in every single open source project no matter how it's big and used, I completely disagree. But again, it's my opinion and here's not the right place for this discussion.

I think, this is the issue we have to solve. We need to enable you to modify the schema after the ORM has generted it from the metadata and before it's being used for comparisons with the actual database.

That's the problem the event system resolved. If we can find an alternative way, then the migration path would be clear and sound and will not be a feature removal.

Do you think, we should enable you configure vendor-specific tweaks like that in the ORM?

IMHO no, it's not a thing the ORM should handle. It is a detail that has no space in the ORM, but the underlying library (this one) should do.

You should be abler to configure patterns of table names that should be ignored during schema comparisons, shouldn't you? I have to look that up though, not entirely sure about how to configure that.

I try to explain it better: I don't want to simply ignore some assets, I need to generate them alongside the tables and columns of the schema generated by the ORM. Solving the problem of modifying the schema generated by the ORM before passing it to DBAL will probably work for these two.
In any case, you should allow to modify and inject custom SQL in the process, or we have the same problem.

No, if those were our only problems with the event system, we wouldn't have deprecated it. You are right, a PSR-4 dispatcher would be the solution here.

I did not write that they are the only problems, but that we shouldn't consider them as valid reasons for this change, so we can remove them from the discussion.

I agree. If you want to work on switching the ORM to PSR-14, don't hesitate do investigate a possible migration path.

Ok, I'll do.

@derrabus
Copy link
Member

derrabus commented Nov 6, 2022

On the "it's free/my free time and work" that is used in every single open source project no matter how it's big and used, I completely disagree.

Well then I don't know why I waste any more of my free-time on having a this conversation with you. If we're not the first open-source project to tell you that, maybe your attitude is the problem?

But again, it's my opinion and here's not the right place for this discussion.

The way you lecture us on how our development process should look like is really disrespectful. "This is my opinion" is really a weak argument for any conversation. If you just want to state your opinion, keep it for yourself next time.

That's the problem the event system resolved.

No, the event system healed a missing extension point. You hooked into the DBAL because you could not hook into the ORMs schema generation.

Do you think, we should enable you configure vendor-specific tweaks like that in the ORM?

IMHO no, it's not a thing the ORM should handle. It is a detail that has no space in the ORM, but the underlying library (this one) should do.

All right.

I try to explain it better: I don't want to simply ignore some assets, I need to generate them alongside the tables and columns of the schema generated by the ORM. Solving the problem of modifying the schema generated by the ORM before passing it to DBAL will probably work for these two. In any case, you should allow to modify and inject custom SQL in the process, or we have the same problem.

Okay, so we should really try to build that extension point in the ORM. Thank you for those answers, that was really helpful.

@alekitto
Copy link
Contributor

alekitto commented Nov 6, 2022

No, the event system healed a missing extension point. You hooked into the DBAL because you could not hook into the ORMs schema generation.

I cannot hook into the ORM schema generation, but even if I could, it will not resolve the point of setting vendor-specific details on how the table/view/... should be created.

To be more clear, I'll give you an example: the buildCreateTableSQL method does not contain a way to completely override the generated SQL and the Table class does not contain something like the columnDefinition property. This means that if I want to override the way the asset is created, now I cannot do it, and the ORM hook after the schema generation will not help in doing so.

Also, appending custom SQL to the generated asset (schema/table/view/index/etc) is not possible with the current objects.
Hooking in the ORM processes will not solve these problems, not with the objects and tools we have at the moment.

I did not meant to hurt or offend anyone, but you're going down on a personal level in the last message.

"This is my opinion" is really a weak argument for any conversation.

Sorry, but on if, when and how to deprecate something, every decision is opinion based. So "this is my opinion" is the only thing that counts, because there are no technical reasons to remove something that works and worked well for years.
Also you have never written "IMHO" under an issue/PR on github? You're really saying that everyone expressing his own opinion is wasting his time?

maybe your attitude is the problem?
keep it for yourself next time.

I really have to answer these statements? And I am the one who's disrespectful?

@derrabus
Copy link
Member

derrabus commented Nov 6, 2022

I did not meant to hurt or offend anyone,

Well, but you have and you've made it very clear that you don't care.

there are no technical reasons to remove something that works and worked well for years.

You'd be surprised.

You're really saying that everyone expressing his own opinion is wasting his time?

I don't.

maybe your attitude is the problem?
keep it for yourself next time.

I really have to answer these statements?

No.

And I am the one who's disrespectful?

Yes.

@derrabus
Copy link
Member

derrabus commented Nov 7, 2022

To anyone who had to witness this unfortunate exchange of messages:

The Doctrine project values constructive feedback from users of our libraries. If a change that we've shipped caused trouble in one of your projects, get in touch with us. We are very careful not to break downstream code, but if we do, it certainly does not happen on purpose.

⚠️ That being said, if I have to read that one of my fellow maintainers, who has invested a lot of work hours in maintaining and modernizing this library, "lacks vision" and that the way he managed one particular change is "not acceptable" – Crap like that that really gets me on the fence. In the last years, I have seen fine people retiring from open-source because of stress and mental health issues. Let me be crystal clear: I won't tolerate this kind of bullying here.

Back to topic: I understand that if you rely heavily on DBAL's events, the deprecation of the event system might appear a bit premature. But as of today, DBAL 3 is still maintained and the event system is still working. We've release DBAL 4 as a first beta and don't have a release date for a final version yet.

Right now, you can help us smoothen the upgrade path and shape the 4.0 release with us. The Doctrine project is maintained by very few people in their free-time. Any additional help is appreciated.

I have created issues for the 3.6.0 milestone from the feedback I've gathered after the 3.5 release. Comment on those or open new issues if you think, we've missed something. This issue will be locked now.

@doctrine doctrine locked as too heated and limited conversation to collaborators Nov 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants