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

Possible mergeable classes for merging code bases #1261

Open
DavoudEshtehari opened this issue Sep 11, 2021 · 30 comments
Open

Possible mergeable classes for merging code bases #1261

DavoudEshtehari opened this issue Sep 11, 2021 · 30 comments
Assignees
Labels
➕ Code Health Issues/PRs that are targeted to source code quality improvements.

Comments

@DavoudEshtehari
Copy link
Contributor

DavoudEshtehari commented Sep 11, 2021

The main aim of this ticket is to clarify the project progress and having contribution with who is interested in it.

At the first step, we've prepared a list of possible mergeable files with their types which maybe need some pruning. Then, priority could be declared before starting to merge.

Mergable files list
File & PR Type Group Priority
DbConnectionStringCommon.cs #1265 DbConnectionStringDefaults DbConnectionStringKeywords DbConnectionStringSynonyms DbConnectionStringBuilderUtil Common  1
DbConnectionOptions.Common.cs (core) DbConnectionOptions.cs #1279 DbConnectionOptions KEY SYNONYM Common  1
AdapterUtil.cs AdapterUtil.Drivers.cs (core) AdapterUtil.SqlClient.cs (core) #1306 ADP Common  1
StringsHelper.cs #1288 StringsHelper Common 1
DbConnectionClosed.cs DbConnectionClosed DbConnectionBusy DbConnectionClosedBusy DbConnectionClosedConnecting DbConnectionClosedNeverOpened DbConnectionClosedPreviouslyOpened DbConnectionOpenBusy ProviderBase  
DbConnectionInternal.cs DbConnectionInternal ProviderBase  
DbConnectionFactory.cs DbConnectionFactory ProviderBase  
DbConnectionPool.cs #2812 PendingGetConnection PoolWaitHandles State TransactedConnectionList TransactedConnectionPool ProviderBase  
DbConnectionPoolGroup.cs #1371 DbConnectionPoolGroup ProviderBase  
DbConnectionPoolIdentity.cs DbConnectionPoolIdentity.Unix.cs (core) DbConnectionPoolIdentity.Windows.cs (core) DbConnectionPoolIdentity ProviderBase  
DbMetaDataFactory.cs #1278 DbMetaDataFactory ProviderBase  
DbReferenceCollection.cs #2403 DbReferenceCollection CollectionEntry ProviderBase
TimeoutTimer.cs #1273 TimeoutTimer ProviderBase  
SQLResource.cs #1276 SQLResource SqlTypes  
SqlFileStream.cs (fx) SqlFileStream.Windows.cs (core) SqlFileStream SqlTypes  
MetadataUtilsSmi.cs #1339 MetadataUtilsSmi SqlClient.Server  
SmiEventSink.cs #1324 SmiEventSink SqlClient.Server  
SmiEventSink_Default.cs #1324 SmiEventSink_Default SqlClient.Server  
SmiMetaDataProperty.cs #1320 SmiDefaultFieldsProperty SmiMetaDataProperty SmiMetaDataPropertyCollection SmiOrderProperty SmiPropertySelector SmiUniqueKeyProperty SqlClient.Server  
SmiTypedGetterSetter.cs #1321 SmiTypedGetterSetter SqlClient.Server  
SmiXetterAccessMap.cs #1310 SmiXetterAccessMap SqlClient.Server  
SqlDataRecord.cs #1309 SqlDataRecord SqlClient.Server  
SqlSer.cs #1313 BinarySerializeSerializer DummyStream NormalizedSerializer SerializationHelperSql9 Serializer SqlClient.Server  
ValueUtilsSmi.cs #1326 ValueUtilsSmi SqlClient.Server  
AlwaysEncryptedHelperClasses.cs (core) TdsParserHelperClasses.cs #2376 _SqlMetaData _SqlMetaDataSet _SqlMetaDataSetCollection _SqlRPC CallbackType EncryptionOptions PreLoginHandshakeStatus PreLoginOptions RunBehavior TdsParserState FederatedAuthenticationFeatureExtensionData SqlCollation RoutingInfo SqlEnvChange SqlLogin SqlLoginAck SqlFedAuthInfo SqlFedAuthToken SqlMetaDataPriv SqlMetaDataXmlSchemaCollection SqlMetaDataUdt SqlReturnValue MultiPartTableName SslProtocolsHelper SqlClient  
AlwaysEncryptedKeyConverter.Cng.cs (fx) AlwaysEncryptedKeyConverter.CrossPlatform.cs (core) KeyConverter SqlClient  
LocalDBAPI.cs LocalDBAPI.Common.cs (core) LocalDBAPI.uap.cs (core) LocalDBAPI.Unix.cs (core) LocalDBAPI.Windows.cs (core) LocalDBAPI SqlClient  
SimulatorEnclaveProvider.cs (fx) SimulatorEnclaveProvider.NetCoreApp.cs (core) #1419 SimulatorEnclaveProvider SqlClient  
SqlAuthenticationProviderManager.cs SqlAuthenticationProviderManager.NetCoreApp.cs (core) SqlAuthenticationProviderManager.NetStandard.cs (core) SqlAuthenticationProviderManager SqlAuthenticationInitializer SqlAuthenticationProviderConfigurationSection SqlClientAuthenticationProviderConfigurationSection SqlClient  
SqlBuffer.cs #1438 SqlBuffer SqlClient  
SqlBulkCopy.cs _ColumnMapping Row Result BulkCopySimpleResultSet SqlBulkCopy SqlClient  
SqlBulkCopyColumnMappingCollection.cs #1285 SqlBulkCopyColumnMappingCollection SqlClient  
SqlCachedBuffer.cs #1280 SqlCachedBuffer SqlClient  
SqlClientFactory.cs #2369 SqlClientFactory SqlClient  
SqlClientMetaDataCollectionNames.cs #1287 SqlClientMetaDataCollectionNames SqlClient  
SqlColumnEncryptionCertificateStoreProvider.Windows.cs (core) SqlColumnEncryptionCertificateStoreProvider.cs (fx) SqlColumnEncryptionCertificateStoreProvider.Unix.cs (core) SqlColumnEncryptionCertificateStoreProvider SqlClient  
SqlColumnEncryptionCngProvider.cs (fx) SqlColumnEncryptionCngProvider.Windows.cs (core) SqlColumnEncryptionCngProvider.Unix.cs (core) SqlColumnEncryptionCngProvider #2501 SqlClient  
SqlColumnEncryptionCspProvider.cs (fx) SqlColumnEncryptionCspProvider.Windows.cs (core) SqlColumnEncryptionCspProvider.Unix.cs (core) SqlColumnEncryptionCspProvider SqlClient  
SqlColumnEncryptionEnclaveProvider.cs SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs (core) SqlColumnEncryptionEnclaveProvider SqlClient  
SqlCommand.cs SqlCommand SqlClient  
SqlCommandBuilder.cs #1284 SqlCommandBuilder SqlClient  
SqlCommandSet.cs #1286 SqlCommandSet SqlClient  
SqlConnection.cs SqlConnectionHelper.cs SqlConnection SqlClient  
SqlConnectionFactory.cs SqlConnectionFactory.AssemblyLoadContext.cs (core) SqlConnectionFactory SqlClient  
SqlConnectionPoolGroupProviderInfo.cs #1323 SqlConnectionPoolGroupProviderInfo SqlClient  
SqlConnectionPoolKey.cs #1292 SqlConnectionPoolKey SqlClient  
SqlConnectionString.cs #1329 #1359 DEFAULT KEY SYNONYM TYPESYSTEMVERSION TRANSACTIONBINDING SqlClient  1
SqlConnectionString.cs SqlConnectionString.NetCoreApp.cs (core) #1329 #1359 SqlConnectionString SqlClient  
SqlConnectionStringBuilder.cs #1349 SqlConnectionStringBuilder SqlClient  
SqlDataAdapter.cs #1295 SqlDataAdapter    
SqlDataReader.cs #1309 SqlDataReader SqlClient  
SqlDelegatedTransaction.cs SqlDelegatedTransaction.NetCoreApp.cs (core) SqlDelegatedTransaction.NetStandard.cs (core) SqlDelegatedTransaction #2861 SqlClient  
SqlDependency.cs #1299 SqlDependency SqlClient  
SqlDependencyListener.cs #1308 SqlDependencyProcessDispatcher SqlClient  
SqlDependencyUtils.cs #1370 #2812 SqlDependencyUtils.AppDomain.cs (core) SqlDependencyUtils.AssemblyLoadContext.cs (core) SqlDependencyPerAppDomainDispatcher SqlClient  
SqlEnums.cs #1317 MetaType TdsDateTime SqlClient  
SqlError.cs #1322 SqlError SqlClient  
SqlErrorCollection.cs #1305 SqlErrorCollection SqlClient  
SqlException.cs #1300 SqlException SqlClient  
SqlInfoMessageEvent.cs #1311 SqlInfoMessageEventArgs SqlClient  
SqlInternalConnection.cs #1598 SqlInternalConnection SqlClient  
SqlInternalConnectionTds.cs SqlInternalConnectionTds SessionStateRecord SessionData ServerInfo SqlClient  
SqlInternalTransaction.cs #1346 SqlInternalTransaction SqlClient  
Sqlmetadatafactory.cs #1315 sqlmetadatafactory SqlClient  
SqlNotificationEventArgs.cs #1314 SqlNotificationEventArgs SqlClient  
SqlParameter.cs #1354 DataFeed StreamDataFeed TextDataFeed XmlDataFeed SqlParameter SqlClient  
SqlQueryMetadataCache.cs #1316 SqlQueryMetadataCache SqlClient  
SqlReferenceCollection.cs #1303 SqlReferenceCollection SqlClient  
SqlSequentialStream.cs #1345 SqlSequentialStream SqlClient  
SqlSequentialTextReader.cs #1343 SqlSequentialTextReader SqlUnicodeEncoding SqlClient  
SqlStream.cs #1337 SqlStream SqlCachedStream SqlStreamingXml SqlClient  
SqlTransaction.cs #1353 SqlTransaction SqlClient  
SqlUtil.cs #2503 #2533 AsyncHelper SQL SQLMessage SqlServerEscapeHelper SysTxForGlobalTransactions SqlClient  
TdsEnums.cs #1369 TdsEnums ActiveDirectoryAuthentication ParsingErrorState SniContext SqlConnectionColumnEncryptionSetting SqlConnectionOverrides SqlCommandColumnEncryptionSetting SqlConnectionAttestationProtocol SqlConnectionIPAddressPreference SqlAuthenticationMethod TransparentNetworkResolutionState DescribeParameterEncryptionResultSet1 DescribeParameterEncryptionResultSet2 DescribeParameterEncryptionResultSet3 SqlClient  
TdsParser.cs TdsParser.NetCoreApp.cs (core) TdsParser.NetStandard.cs (core) TdsParser.RegisterEncoding.cs (core) TdsParser.Unix.cs (core) TdsParser.Windows.cs (core) TdsParser SqlClient  
TdsParserSafeHandles.cs #1604 SNILoadHandle SNIHandle SNIPacket WritePacketCache SqlClient  
TdsParserSessionPool.cs #1595 TdsParserSessionPool SqlClient  
TdsParserStateObject.cs #1520, #1844, #2168, #2254, #2302 TdsParserStateObject LastIOTimer SqlClient  
TdsParserStaticMethods.cs #1588 #2814 TdsParserStaticMethods SqlClient  
SqlFileStream.cs (fx) SqlFileStream.Windows.cs (core) #2398 SqlFileStream SqlTypes  
@DavoudEshtehari DavoudEshtehari added the ➕ Code Health Issues/PRs that are targeted to source code quality improvements. label Sep 11, 2021
@Wraith2
Copy link
Contributor

Wraith2 commented Sep 11, 2021

I think KeyConverter is done. There isn't a way to merge further for two reasons, 1) netstandard doesn't contain elliptical curve 2) netcore and netfx instantiate crypto providers in entirely different ways that I couldn't abstract any further.

SqlBuffer is very close to being done the remaining differences are because there is allocation free guid support in netcore that isn't in netfx. This means that SqlDataReader changes need to be ported to add that feature on netfx.

Some classes like TdsParser, TdsParserStateObject, SqlDataReader, SqlCommand are very large and I don't think we can do in a single PR, it would be impossible to review. I believe the way to do those types is a many small PR's which take identical functionality from both into a new shared version of the file slowly reducing each project specific file to the parts which are different and then those can be thoroughly reviewed.

@DavoudEshtehari
Copy link
Contributor Author

Thanks for the comments.
Regarding the KeyConverter, I think we could extract the behavior of the class in the lowest possible abstraction.
I completely agree with keeping the PRs as simple as possible for the sake of review. Based on your idea, the above table doesn't mean each file or type should be merged in a single PR.

@Wraith2
Copy link
Contributor

Wraith2 commented Sep 24, 2021

Looking at some of the merged from @lcheunglci I thought it might be useful to write down some of my knowledge and methodology used in my merges. From what I've gathered:

The nextfx codebase was forked at some point and that fork had a managed implementation of the network interface written so that it could be used on linux for netcore. This means that this codebase now has managed and native versions of the Sql Network Interface (SNI) in the netcore codebase and they are switched out depending on the platform that you restore the nuget package for. You can also force the use of managed network in windows with an appcontext switch. This mostly makes a difference in the core of TdsParser and TdsParserStateObject.

After netcore was forked the codebase was cleaned up a bit. So in general netcore is newer than netfx. However, changes and fixes may have been made to the netcore and netfx codebases independently so there's no guarantee that either was one better than the other they can both contain better versions of any particular function.

The netfx codebase is very very old, it was in the original 1.0 release of netfx and it hasn't always been updated to use the latest features. An example of this is the pool key derivation mechanism on netfx, it uses direct api calls to windows security apis because the managed equivalents were not available or not know to be usable at the time of writing.

This means that any change can be old or new and come from any version of the source code. To merge them you have to try to work out if they are functionally identical or equivalent enough that the difference cannot be observed by users up to and including timing and ordering of operations. This can get complicated and time consuming.

Style between the two codebases is highly variable. In general when merging a file it's a good idea to turn on the compiler Info messages and look through all the possible refactoring options is gives you. You don't have to take all the suggestions just take a look at them and make the code feel like it has the same style as some of the already merged components. The objective is to work towards a coherently styled single codebase where naming and formatting are easy to understand between most files.

@lcheunglci
Copy link
Contributor

Thanks @Wraith2 for your insight. I'll keep that in mind when I'm doing the code base merges. I'm currently starting small particularly focusing on the simpler code merges with the least conflicts before I look at the bigger ones. Your feedback and suggestions are much appreciated.

@lcheunglci
Copy link
Contributor

While I was looking into SqlReferenceCollection.cs in PR #1303 , I noticed a dependency on SqlInternalConnection.cs which I've have merge locally, but noticed another dependency on SqlDataReader.cs, which I also have merged locally. However, after a conversation with @cheenamalhotra, she mentioned there was a change to SqlDataReader.cs in #1019 , so I decided to put that on hold until that PR is approved and merged. In case someone else decided to merge SqlDataReader.cs and/or SqlInternalConnection.cs, I thought I'd mention it here to let you know that the work is in progress.

Kaur-Parminder added a commit to Kaur-Parminder/SqlClient that referenced this issue Oct 4, 2021
Code merge for dotnet#1261 Issue for SmiXetterAccessMap class. Added the common code to .Common.cs class.
@edwardneal
Copy link
Contributor

edwardneal commented Feb 27, 2024

I think I see the PR you're talking about @Wraith2 (#1022), thanks for that. Nowadays, the main problem lies in the ECDiffieHellman class: the creation of an RSA instance from a key blob seems to have been replaced with a managed implementation.

Oddly, .NET Framework 4.6.1 (which implements .NET Standard 2.0) has this class. Other frameworks naturally implement it, so we could potentially have one code path for .NET Standard 2.1 and .NET Framework, then a PlatformNotSupportedException for everything else.

This means that it wouldn't support the platform versions below:

Platform Unsupported version Last release date Vendor supported
Mono < 6.4 6-Nov-2017 ?
Xamarin.iOS < 12.16 5-Aug-2019 No
Xamarin.Mac < 5.16 12-Sep-2019 No (now part of .NET 6 which is supported)
Xamarin.Android < 10.0 5-Sep-2019 No
UWP All ? ?
Unity < 2021.2 25-Oct-2021 No

I personally think it'd be justifiable not to explicitly add support for a platform that the vendors don't support themselves, but not adding anything for UWP is a pity. I don't think there's a way to include it though.

Naturally if SqlClient as a whole drops support for .NET Standard (2.0 or more broadly) then this problem becomes academic!

@JRahnama
Copy link
Contributor

@Wraith2 So removing netstandard support will improve the abaility to merge code?

it definitely will do and specifically NetStandard 2.0

@edwardneal
Copy link
Contributor

Just as an update on this: PRs #2369, #2376, #2383 and #2390 will merge SqlClientFactory, AlwaysEncryptedHelperClasses, TdsParserHelperClasses, AAsyncCallContext and DbConnectionPoolIdentity. They also lay the groundwork for the merge of SqlDataReader. I think I can also safely merge DbConnectionFactory, DbReferenceCollection, DbConnectionClosed, SqlAuthenticationProviderManager and SqlFileStream without raising too many eyebrows - the implementations are identical (or so close to identical that it barely matters.)

I can see the open issue and PR to terminate .NET Standard support, and I'll wait for this to be merged before dealing with the various encryption/enclave providers.

In one situation, specific functionality will need to be locked behind conditional compilation: the .NET Framework's MDS supports the Context Connection statement, which is used when it's running inside the SQL Server process as part of its CLR integration. By definition, .NET Core will never support this particular integration, and if I'm understanding the documentation correctly, SQL Server Language Extensions is out-of-process and thus wouldn't use it either. I'll wait to see what the supported platforms for MDS will end up being - if it won't support .NET Framework at all, we don't need it (or any of the auxiliary classes/functionality it brings.)

This leaves the more complicated cases, where functionality and support have diverged. So far I've come across a few of these:

  • MDS has differing connectivity capabilities for SQL Server. The .NET Core library can connect to SQL 2005+, while the .NET Framework library can also connect to SQL 7.0 and 2000. While it's possible to maintain that difference, I can see an earlier issue (Connection to SQL Server 2000 fails with unhelpful message; missing supported versions documentation #1841) which indicates that we don't support it. I don't want to raise a PR removing support without confirmation that this is the right thing to do.
  • The .NET Framework MDS library will try to create a LocalDB instance before connecting to it, while the .NET Core library just tries to connect to it.
  • .NET Core and .NET Framework expose statistics in different ways - Core uses event counters, Framework uses performance counters. This'll need an thin translation layer, since it'll need to be exposed as metrics for another issue.

Once there's the .NET Standard PR is implemented and there's nothing more I can merge, I'll take another look at these situations and see if they're as difficult as they look.

I'm not planning to look at TdsParser, SqlCommand or SqlConnection any time soon. These probably need someone with a much better understanding of the library's history than me.

@edwardneal
Copy link
Contributor

edwardneal commented May 16, 2024

@DavoudEshtehari SqlClientFactory has been merged in #2369. A lot of the other merge PRs pre-date the removal of support for .NET Standard - I'll bring these up to date as they're prioritised and reviewed.

In the wake of that removal, #2501 merges three of the four SqlColumnEncryptionKeyStoreProvider derivatives. These classes are almost identical between .NET Core and .NET Framework.

The remaining derived class is SqlColumnEncryptionCertificateStoreProvider, which is a little more complex: the .NET Framework version uses RSACryptoServiceProvider and directly accesses the private keys of certificates, while the .NET Core version uses the GetRSAPrivateKey extension method. I'll merge the class once I've tested with both CAPI and CNG keys.

Once #2501 and the extra PR (edit: #2521) have been merged, there'll be room for Unix support for Always Encrypted.

@edwardneal
Copy link
Contributor

edwardneal commented Sep 15, 2024

I've reached a stopping point with the merge, so it's now just a matter of triage. To summarise the table I've been using to keep track:

Files covered by PRs

File .NET Framework path .NET Core path Associated PR
AdapterSwitches src/Microsoft/Data/Common - #2828
NativeMethods; SafeNativeMethods; UnsafeNativeMethods src/Microsoft/Data/Common - #2828
DbConnectionPool src/Microsoft/Data/ProviderBase src/Microsoft/Data/ProviderBase #2812
SqlGenericUtil src/Microsoft/Data/Sql - #2814
AAsyncCallContext - src/Microsoft/Data/SqlClient #2383
AlwaysEncryptedHelperClasses - src/Microsoft/Data/SqlClient #2376
SqlCertificateCallbacks src/Microsoft/Data/SqlClient - #2831
SqlClientOriginalAddressInfo src/Microsoft/Data/SqlClient - #2831
SqlColumnEncryptionCngProvider src/Microsoft/Data/SqlClient src/Microsoft/Data/SqlClient #2501
SqlColumnEncryptionCspProvider src/Microsoft/Data/SqlClient src/Microsoft/Data/SqlClient #2501
SqlColumnEncryptionEnclaveProvider src/Microsoft/Data/SqlClient src/Microsoft/Data/SqlClient #2501
SqlDelegatedTransaction src/Microsoft/Data/SqlClient src/Microsoft/Data/SqlClient #2861
SqlDependencyUtils src/Microsoft/Data/SqlClient - #2814
SqlFileStream src/Microsoft/Data/SqlClient src/Microsoft/Data/SqlClient; src/Microsoft/Data/SqlTypes #2898
TdsParserHelperClasses src/Microsoft/Data/SqlClient src/Microsoft/Data/SqlClient #2376
TdsParserStaticMethods - src/Microsoft/Data/SqlClient #2814
UnsafeNativeMethods src/Microsoft/Data/SqlTypes - #2828

SQLCLR, code access security types

All of these depend upon #2862. There's not much code to merge here, just a lot of files. I think there'll probably be 3-4 PRs for these.

File .NET Framework path
DBDataPermissionAttribute src/Common/src/Microsoft/Data/Common
NameValuePermission src/Common/src/Microsoft/Data/Common
DBConnectionString src/Microsoft/Data/Common
Smi*; TriggerAction src/Microsoft/Data/SqlClient/Server
SqlClientPermission src/Microsoft/Data/SqlClient
SqlClientWrapperSmiStream src/Microsoft/Data/SqlClient
SqlClientWrapperSmiStreamChars src/Microsoft/Data/SqlClient
SqlDataReaderSmi; SqlInternalConnectionSmi; SqlSequentialStreamSmi; SqlSequentialTextReaderSmi src/Microsoft/Data/SqlClient
SqlStreamChars src/Microsoft/Data/SqlClient

Metrics, logging

These use two different mechanisms between .NET Framework and .NET Core, and they also record metrics at slightly different times. It might be better to merge the API surface and verify the metric timings as part of any future OpenTelemetry work. The issue tracking that is #2210 and #2211.

File .NET Framework path .NET Core path
DbConnectionPoolCounters src/Microsoft/Data/ProviderBase -
SqlClientDiagnostic - src/Microsoft/Data/SqlClient
SqlClientDiagnosticListenerExtensions - src/Microsoft/Data/SqlClient
SqlClientEventSource - src/Microsoft/Data/SqlClient
SqlDiagnosticListener - src/Microsoft/Data/SqlClient

Native SNI

This'll change the public-facing dependencies for the NuGet packages. Barring any objections, I'm planning to change the .NET Framework package to reference Microsoft.Data.SqlClient.SNI.runtime. This'll mean that there's one architecture-dependent DLL file in the resultant builds, not three DLLs which are toggled between at runtime.

File .NET Framework path .NET Core path
SNINativeManagedWrapperARM64; SNINativeManagedWrapperX64; SNINativeManagedWrapperX86; SNINativeManagedWrapper src/Microsoft/Data/Interop src/Interop

TDS parser

I'm pretty confident that the majority of the logic is identical, it's just obscured by the fact that only one codebase was refactored. There are probably some methods which can be merged as-is, but for the vast majority of cases I think we'll just need to repeat that refactor piecemeal.

I'm not planning to start until #2714 is merged, given how deeply any refactor work will touch the state machine.

@Wraith2
Copy link
Contributor

Wraith2 commented Sep 15, 2024

The work to merge the two codebases has been going on for a long time. The problem is always testing and review.

@edwardneal
Copy link
Contributor

I've definitely seen that - there's a lot of history here. A lot of the problem seems to be that we've got a mixture of different types of changes:

  1. Purely syntax-based changes which don't impact the compiler output, but which balloon the diff - methods being rearranged in a class, automatic properties, => syntax, etc.
  2. Infrastructure code which is no longer referenced, or which has been reorganised - PInvokes which are no longer referenced, others which have been moved to separate files
  3. Structural refactors
  4. "Real" feature/implementation differences (like SQL Azure's read-only failover partner support in SqlInternalConnectionTds, which only exists in .NET Framework)

Reviewing and testing PRs which contain any combination of those is always going to be tricky; many of the remaining classes have so much of the first two types of change that it's obscuring the changes which need the most review. I've seen a few "style change" PRs which touch large parts of both codebases. Those are disruptive when merged and their size makes them harder to review, but they might be a safer way to fix those first type of change and free up some bandwidth to review the more important changes.

@MichelZ
Copy link

MichelZ commented Nov 1, 2024

Is there value in moving 100% matches first? e.g. in TdsParser there is PutSession, which is 100% identical.
I know it was touched upon in #1261 (comment), but I'm not sure what the current sentiment is here?

Something like this: 66f975c

@MichelZ
Copy link

MichelZ commented Nov 1, 2024

I also wonder if it makes sense to equalize any code style changes between netfx and netcore by lifting up netfx to be the same as netcore (and if this should be a separate effort from merging)

Something like this: 4331089

@Wraith2
Copy link
Contributor

Wraith2 commented Nov 1, 2024

I've tried both approaches. The throughput limitations are always review time and release cadence. We can only go as far as the MS team allow and they're busy.

@MichelZ
Copy link

MichelZ commented Nov 1, 2024

So code style changes (for the sake of equalizing) should take the least time to review I guess?

@Wraith2
Copy link
Contributor

Wraith2 commented Nov 1, 2024

In theory but in practice any review will take the same amount of time to happen so you have to choose what is more important to use your review quota for. Do you want to make material changes and improve the library or do you want to improve the quality of the codebase in a way that does not affect users?

@MichelZ
Copy link

MichelZ commented Nov 1, 2024

Yep, understood. That's why I'd like to get some guidance from MS on what they prefer we'd do before starting new PR's that they don't want

@edwardneal
Copy link
Contributor

Speaking personally here...

I've found my approach to PRs drifting into a cycle: start with a small PR which touches as little as possible and aligns some part of the public API (the API surface or behavioural) between netcore and netfx; follow up with a set of larger PRs which do more of the heavy lifting for that change. I've been trying to align the small PRs with the days/~fortnight before a GitHub milestone. Hopefully this should mean that the releases are met by easier-to-review community PRs, and the team gets a few, larger PRs when there's less pressure to review them. The Context Connection PR is a decent example of this - it's a small PR which functionally removes about 8k lines of code and half a dozen files. I'm not submitting those larger removals until after 6.0!

Separately to this: the point around code style merges is good. I don't have any real opinions on whether we should have a series of "big bang" PRs which target a few files and apply every code style change at the same time, or some other approach. My only two opinions here are that we should avoid making very large code style adjustments as part of a merge, and that we shouldn't roll out a repo-wide change which needs manual merge conflict resolution in lots of PRs without some forewarning. I'm happy to contribute to whichever approach makes sense besides that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
➕ Code Health Issues/PRs that are targeted to source code quality improvements.
Projects
None yet
Development

No branches or pull requests

8 participants